Segmentation fault: 11 ? C++ - c++

Can you tell why does this generate segmentation error? Problem seems to occur when operator[] is called and when I don't call it, goes fine. operator[] is supposed to return a reference to the element with index i.. any help would be great..
//dynamic_array.cpp file
#include <iostream>
#include "dynamic_array.h"
using namespace std;
dynamic_array::dynamic_array() {
int *array;
array=new int[4];
array[0]=3;
size = 4;
allocated_size = 5;
}
dynamic_array::~dynamic_array() {
delete [] array;
}
int dynamic_array::get_size(void) const {
return size;
}
int dynamic_array::get_allocated_size(void) const {
return allocated_size;
}
int& dynamic_array::operator[](unsigned int i) {
return array[i];
}
//test.cpp file
#include <iostream>
#include <stdlib.h>
#include "dynamic_array.h"
using namespace std;
int main() {
dynamic_array a;
cout << a[0];
}
//dynamic_array.h file
using namespace std;
class dynamic_array {
public:
enum {
BLOCK_SIZE = 5,
SUBSCRIPT_RANGE_EXCEPTION = 1,
MEMORY_EXCEPTION = 2,
};
dynamic_array();
~dynamic_array();
int get_size(void) const;
int get_allocated_size() const;
int& operator[](unsigned int i);
class exception {
public:
exception(int n0) { n = n0; };
int n;
};
private:
int *array; // pointer to dynamically allocated memory
int allocated_size; // total number of elements in allocated memory
int size; // number of active elements
};

The local declaration
int *array;
shadows the member array. So the following code uses the local variable, not the member. Hence the member is uninitialized.
Instead of creating your own dynamic array, use std::vector.
That's safer and more convenient.
In other news:
The get prefix in e.g. get_size is a Java-ism.
In C++ a get prefix has no advantage, and it makes the code less readable. For example, standard library containers have a size method, not a get_size.
Using void as a formal argument declaration, as in get_size(void), is a C-ism.
In C it has the important effect of telling the compiler that there really are no arguments, as opposed to any arguments. In C++ () indicates that.
Not having also a const version of operator[] is inconsistent with earlier use of const.
Consistency is very important in programming. Our expectation, e.g. when maintaining code, is that it's consistent. Code that's inconsistent adds costly man-hours to maintenance.
The ALL UPPERCASE identifiers for constants are a Java-ism.
Java lacks a preprocessor, and inherited the all uppercase convention from early C, which lacked const. C++ has both const and a preprocessor. Having const there's generally no need to use #define for constants (as in early C), and having a preprocessor there's a good tecnical reason to not use all uppercase (it conflicts with the convention for macro names). In addition many/most programmers see all uppercase as shouting. It hurts.
The class exception should better be derived from std::exception.
Instead of inventing one's own exception class that can carry an error code, just use std::system_error. That's what it's for. Alternatively, derive a class from std::runtime_error, or use std::runtime_error directly.

The problem is in your constructor
Go like this for the constructor:
dynamic_array::dynamic_array() {
array = new int[4];
array[0] = 3;
size = 4;
allocated_size = 5;
}
the problem is this additinal line of code in the constructor:
int *array;
In your constructor definition, you declared a new local pointer variable named array and you allocated memory for that.
But this variable is local to the constructor and it is not the one declared in your class as may be you believed.

Related

Run-Time Check Failure #2 - Stack around the variable 'e' was corrupted. occurred

#include<iostream>
#include <list>
using namespace std;
class Euler {
private:
int korifes = 0;
int akmes = 0;
int* pinakas[];
public:
void print() { cout << *pinakas[0]; return; }
Euler(int korifess, int akmess);
~Euler() { delete[] *pinakas; }
void addAkmes(int kor1, int kor2);
};
Euler::Euler(int korifess, int akmess) : akmes(akmess), korifes(korifess) {
*pinakas = new int(korifes);
*pinakas[0] = 89;
}
int main() {
Euler e(2, 1);
e.print();
}
Run-Time Check Failure #2 - Stack around the variable 'e' was corrupted. occurred...i can not find where i am wrong in my code.
There are a number of errors in your code, all related to the nature of the pinakas member variable. As it stands, you are declaring this as an array of pointers (to int), and, furthermore, you are using a non-standard syntax for 'flexible' arrays (the empty []).
I don't normally just paste 'fixed' code as an answer but, in this case, that code (with the added \\\ comments where I've made changes) is likely to be the most succinct way to help you.
Although, as many here will no doubt point out, it is far better to avoid the use of 'raw' pointers and the new and delete operators, and use the std::vector container, instead.
#include <iostream>
#include <list>
//using namespace std;/// This is considered 'bad practice' by many programmers
using std::cout;/// Just use the aspect of the STL that you need!
class Euler {
private:
int korifes = 0;
int akmes = 0;
int* pinakas;/// This will point an 'array' of integers
public:
void print() {
cout << pinakas[0]; return;/// No longer any need for the dereference (*)
}
Euler(int korifess, int akmess);
~Euler() {
delete[] pinakas;/// No need for the dereference (*)
}
// void addAkmes(int kor1, int kor2);/// You haven't provided an actual definition for this, but your never use it!
};
Euler::Euler(int korifess, int akmess) : akmes(akmess), korifes(korifess)/// NOTE: Members are initialized in DECLARATION order!
{
pinakas = new int[korifes];/// Use "[]" (not "()") to allocate an array!
pinakas[0] = 89;/// No need for the dereference (*)
}
Feel free to ask for any further clarification and/or explanation.

passing an array into a class function from another class's constructor

Sorry for the confusing title, basically I have created two classes, one is an object, and the other being a box that contains an array of such objects. so what I want to do is create a function/constructor inside the object class that takes in an array of ints and stores them inside the box. I want to be able to call this function through the box class constructor to initialize these objects. So ive tried something like below but it isnt working at all, since only the first value of the array gets passed through. What am I doing wrong?
#include <iostream>
#include <string>
class object{
string objectName;
int values[];
public:
void createObject(int[]);
}
class Box{
object objects[100];
public:
Box();
}
Box::Box (void){
int array1[2];
int array2[15];
object[1].createObject(array1);
object[2].createObject(array2);
}
Object::Object(int Values[]){
values = Values;
}
You should really use std::vector. The problem with arrays is that they decay to pointers when passed as arguments to functions. As a consequence, If you want to store a private copy of the elements you are forced to use heap-allocated objects and consequently do memory management by hand (with all the pain it causes).
It is much better to rely on data members that permit applying the rule of zero.
Here's a tentative solution:
#include <iostream>
#include <string>
#include <vector>
class object {
public:
object(std::vector<int> const& v, std::string const& object_name): v_(v.begin(), v.end()), object_name_(object_name) {}
private:
std::vector<int> v_;
std::string object_name_;
};
class box {
public:
box(std::vector<object> const& objects): objects_(objects) {};
private:
std::vector<object> objects_;
};
I recommend you instead use a std::vector. Arrays don't really work well being passed to functions. When you define Object::Object(int Values[]) you are simply passing the first element of this array by value. If you were to use vectors, the function would look like this:
Object::Object(std::vector<int> &Values):
values(Values)
{
}
The problem with the code is in your thinking on what the array is. In C++, all an array is, is a memory pointer. The language allows you to pass an index into the array pointer to access whatever chunk of data lives at that index.
Whenever you pass arrays between functions or classes, pass the array name only. It will be interpreted as a pointer, and won't copy any data. When you do this, you must also pass the length of the array.
Granted, most people stick with vector<> because it's easier, takes care of memory leaks (mostly) and is VERY efficient. But I like doing it myself. It's good for you. I would try:
#include <iostream>
#include <string>
class Object
{
string _objectName;
int *_values;
int _myLength;
Object();
~Object();
void createObject(int *pValues, int arrLength);
}
class Box
{
_Object objects[100];
Box();
}
Box::Box(void) {
int array1[2];
int array2[15];
object[1].createObject(array1, 2);
object[2].createObject(array2, 15);
}
Object::Object() {
_values = null_ptr;
_myLength = 0;
}
Object::~Object() {
delete[] _values;
}
void Object::createObject(int *pvalues, int arrLength) {
_myLength = arrLength;
_values = new int[_myLength];
for(int ndx=0; ndx<arrLength; ndx++) {
_values[ndx] = pvalues[ndx];
}
}
-CAUTION-
I just adapted your code you provided, and added some conventions. There are a couple places in the code where I'm not sure what the purpose is, but there you go. This should give you a good head start.

Trouble implementing min Heaps in C++

I'm trying to implement a minheap in C++. However the following code keeps eliciting errors such as :
heap.cpp:24:4: error: cannot convert 'complex int' to 'int' in assignment
l=2i;
^
heap.cpp:25:4: error: cannot convert 'complex int' to 'int' in assignment
r=2i+1;
^
heap.cpp: In member function 'int Heap::main()':
heap.cpp:47:16: error: no matching function for call to 'Heap::heapify(int [11], int&)'
heapify(a,i);
^
heap.cpp:47:16: note: candidate is:
heap.cpp:21:5: note: int Heap::heapify(int)
int heapify(int i) //i is the parent index, a[] is the heap array
^
heap.cpp:21:5: note: candidate expects 1 argument, 2 provided
make: * [heap] Error 1
#include <iostream>
using namespace std;
#define HEAPSIZE 10
class Heap
{
int a[HEAPSIZE+1];
Heap()
{
for (j=1;j<(HEAPISZE+1);j++)
{
cin>>a[j];
cout<<"\n";
}
}
int heapify(int i) //i is the parent index, a[] is the heap array
{
int l,r,smallest,temp;
l=2i;
r=2i+1;
if (l<11 && a[l]<a[i])
smallest=l;
else
smallest=i;
if (r<11 && a[r]<a[smallest])
smallest=r;
if (smallest != i)
{
temp = a[smallest];
a[smallest] = a[i];
a[i]=temp;
heapify(smallest);
}
}
int main()
{
int i;
for (i=1;i<=HEAPSIZE;i++)
{
heapify(a,i);
}
}
}
Ultimately, the problem with this code is that it was written by someone who skipped chapters 1, 2 and 3 of "C++ for Beginners". Lets start with some basics.
#include <iostream>
using namespace std;
#define HEAPSIZE 10
Here, we have included the C++ header for I/O (input output). A fine start. Then, we have issued a directive that says "Put everything that is in namespace std into the global namespace". This saves you some typing, but means that all of the thousands of things that were carefully compartmentalized into std:: can now conflict with names you want to use in your code. This is A Bad Thing(TM). Try to avoid doing it.
Then we went ahead and used a C-ism, a #define. There are times when you'll still need to do this in C++, but it's better to avoid it. We'll come back to this.
The next problem, at least in the code you posted, is a misunderstanding of the C++ class.
The 'C' language that C++ is based on has the concept of a struct for describing a collection of data items.
struct
{
int id;
char name[64];
double wage;
};
It's important to notice the syntax - the trailing ';'. This is because you can describe a struct and declare variables of it's type at the same time.
struct { int id; char name[64]; } earner, manager, ceo;
This declares a struct, which has no type name, and variables earner, manager and ceo of that type. The semicolon tells the compiler when we're done with this statement. Learning when you need a semicolon after a '}' takes a little while; usually you don't, but in struct/class definition you do.
C++ added lots of things to C, but one common misunderstanding is that struct and class are somehow radically different.
C++ originally extended the struct concept by allowing you to describe functions in the context of the struct and by allowing you to describe members/functions as private, protected or public, and allowing inheritance.
When you declare a struct, it defaults to public. A class is nothing more than a struct which starts out `private.
struct
{
int id;
char name[64];
double wage;
};
class
{
public:
int id;
char name[64];
double wage;
};
The resulting definitions are both identical.
Your code does not have an access specifier, so everything in your Heap class is private. The first and most problematic issue this causes is: Nobody can call ANY of your functions, because they are private, they can only be called from other class members. That includes the constructor.
class Foo { Foo () {} };
int main()
{
Foo f;
return 0;
}
The above code will fail to compile, because main is not a member of Foo and thus cannot call anything private.
This brings us to another problem. In your code, as posted, main is a member of Foo. The entry point of a C++ program is main, not Foo::main or std::main or Foo::bar::herp::main. Just, good old int main(int argc, const char* argv[]) or int main().
In C, with structs, because C doesn't have member functions, you would never be in a case where you were using struct-members directly without prefixing that with a pointer or member reference, e.g. foo.id or ptr->wage. In C++, in a member function, member variables can be referenced just like local function variables or parameters. This can lead to some confusion:
class Foo
{
int a, b;
public:
void Set(int a, int b)
{
a = a; // Erh,
b = b; // wat???
}
};
There are many ways to work around this, but one of the most common is to prefix member variables with m_.
Your code runs afoul of this, apparently the original in C passed the array to heapify, and the array was in a local variable a. When you made a into a member, leaving the variable name exactly the same allowed you not to miss the fact that you no-longer need to pass it to the object (and indeed, your heapify member function no-longer takes an array as a pointer, leading to one of your compile errors).
The next problem we encounter, not directly part of your problem yet, is your function Heap(). Firstly, it is private - you used class and haven't said public yet. But secondly, you have missed the significance of this function.
In C++ every struct/class has an implied function of the same name as the definition. For class Heap that would be Heap(). This is the 'default constructor'. This is the function that will be executed any time someone creates an instance of Heap without any parameters.
That means it's going to be invoked when the compiler creates a short-term temporary Heap, or when you create a vector of Heap()s and allocate a new temporary.
These functions have one purpose: To prepare the storage the object occupies for usage. You should try and avoid as much other work as possible until later. Using std::cin to populate members in a constructor is one of the most awful things you can do.
We now have a basis to begin to write the outer-shell of the code in a fashion that will work.
The last change is the replacement of "HEAPSIZE" with a class enum. This is part of encapsulation. You could leave HEAPSIZE as a #define but you should expose it within your class so that external code doesn't have to rely on it but can instead say things like Heap::Size or heapInstance.size() etc.
#include <iostream>
#include <cstdint> // for size_t etc
#include <array> // C++11 encapsulation for arrays.
struct Heap // Because we want to start 'public' not 'private'.
{
enum { Size = 10 };
private:
std::array<int, Size> m_array; // meaningful names ftw.
public:
Heap() // default constructor, do as little as possible.
: m_array() // says 'call m_array()s default ctor'
{}
// Function to load values from an istream into this heap.
void read(std::istream& in)
{
for (size_t i = 0; i < Size; ++i)
{
in >> m_array[i];
}
return in;
}
void write(std::ostream& out)
{
for (size_t i = 0; i < Size; ++i)
{
if (i > 0)
out << ','; // separator
out << m_array[i];
}
}
int heapify(size_t index)
{
// implement your code here.
}
}; // <-- important.
int main(int argc, const char* argv[])
{
Heap myHeap; // << constructed but not populated.
myHeap.load(std::cin); // read from cin
for (size_t i = 1; i < myHeap.Size; ++i)
{
myHeap.heapify(i);
}
myHead.write(std::cout);
return 0;
}
Lastly, we run into a simple, fundamental problem with your code. C++ does not have implicit multiplication. 2i is the number 2 with a suffix. It is not the same as 2 * i.
int l = 2 * i;
There is also a peculiarity with your code that suggests you are mixing between 0-based and 1-based implementation. Pick one and stick with it.
--- EDIT ---
Technically, this:
myHeap.load(std::cin); // read from cin
for (size_t i = 1; i < myHeap.Size; ++i)
{
myHeap.heapify(i);
}
is poor encapsulation. I wrote it this way to draw on the original code layout, but I want to point out that one reason for separating construction and initialization is that it allows initialization to be assured that everything is ready to go.
So, it would be more correct to move the heapify calls into the load function. After all, what better time to heapify than as we add new values, keeping the list in order the entire time.
for (size_t i = 0; i < Size; ++i)
{
in >> m_array[i];
heapify(i);
}
Now you've simplified your classes api, and users don't have to be aware of the internal machinery.
Heap myHeap;
myHeap.load(std::cin);
myHeap.write(std::cout);

cannot resize c++ std::vector that's a member variable of a class

code (simplified version)
(part of) the class definition:
struct foo {
std::vector<int> data;
foo(int a=0):data(a+1,0) {}
void resize(int a) {
data.resize(a+1,0);
}
}
The a+1 part is because I want the data to be 1-indexed to simplify some operations.
in global scope:
int k;
foo bar;
in main function:
std::cin>>k;
bar.resize(k);
Later in the main function, there is a call to another member function (in foo) that accesses the data, causing a segmentation fault (segsegv).
After debugging, I found that data.size() returns 0. Which is very unexpected.
After a very long session of debugging, I feel very confident that the problem is with the resizeing, which shouldn't cause any problems (it's from the standard library, after all!).
P.S. Don't accuse me for putting anything in global scope or giving public access to class members. I'm not writing any "real" program, because I'm just practicing for a programming competition.
After a very long session of debugging, I feel very confident that the problem is with the resize
It is almost certain that:
The issue doesn't have anything to do with resize().
You have a memory-related bug somewhere (double delete, uninitialized/dangling pointer, buffer overrun etc).
The thing with memory-related bugs is that they can be completely symptomless until well after the buggy code has done the damage.
My recommendation would be to run your program under valgrind (or at least show us an SSCCE that doesn't work for you).
The following works fine for me
#include <vector>
#include <cstdlib>
struct foo {
std::vector<int> data;
explicit foo(int a=0) : data(a+1, 0) {}
void resize(int a) {
data.resize(a+1, 0);
}
};
int main() {
foo test_foo(1);
for (size_t i = 0; i < 1000; ++i) {
int a = std::rand() % 65536;
test_foo.resize(a);
if (test_foo.data.size() != a + 1)
return 1;
}
return 0;
}

Determine array size in constructor initializer

In the code below I would like array to be defined as an array of size x when the Class constructor is called. How can I do that?
class Class
{
public:
int array[];
Class(int x) : ??? { }
}
You folks have so overcomplicated this. Of course you can do this in C++. It is fine for him to use a normal array for efficiency. A vector only makes sense if he doesn't know the final size of the array ahead of time, i.e., it needs to grow over time.
If you can know the array size one level higher in the chain, a templated class is the easiest, because there's no dynamic allocation and no chance of memory leaks:
template < int ARRAY_LEN > // you can even set to a default value here of C++'11
class MyClass
{
int array[ARRAY_LEN]; // Don't need to alloc or dealloc in structure! Works like you imagine!
}
// Then you set the length of each object where you declare the object, e.g.
MyClass<1024> instance; // But only works for constant values, i.e. known to compiler
If you can't know the length at the place you declare the object, or if you want to reuse the same object with different lengths, or you must accept an unknown length, then you need to allocate it in your constructor and free it in your destructor... (and in theory always check to make sure it worked...)
class MyClass
{
int *array;
MyClass(int len) { array = calloc(sizeof(int), len); assert(array); }
~MyClass() { free(array); array = NULL; } // DON'T FORGET TO FREE UP SPACE!
}
You can't initialize the size of an array with a non-const dimension that can't be calculated at compile time (at least not in current C++ standard, AFAIK).
I recommend using std::vector<int> instead of array. It provides array like syntax for most of the operations.
Use the new operator:
class Class
{
int* array;
Class(int x) : array(new int[x]) {};
};
I don't think it can be done. At least not the way you want. You can't create a statically sized array (array[]) when the size comes from dynamic information (x).
You'll need to either store a pointer-to-int, and the size, and overload the copy constructor, assignment operator, and destructor to handle it, or use std::vector.
class Class
{
::std::vector<int> array;
Class(int x) : array(x) { }
};
Sorry for necroing this old thread.
There is actually a way to find out the size of the array compile-time. It goes something like this:
#include <cstdlib>
template<typename T>
class Class
{
T* _Buffer;
public:
template<size_t SIZE>
Class(T (&static_array)[SIZE])
{
_Buffer = (T*)malloc(sizeof(T) * SIZE);
memcpy(_Buffer, static_array, sizeof(T) * SIZE);
}
~Class()
{
if(_Buffer)
{
free(_Buffer);
_Buffer = NULL;
}
}
};
int main()
{
int int_array[32];
Class<int> c = Class<int>(int_array);
return 0;
}
Alternatively, if you hate to malloc / new, then you can create a size templated class instead. Though, I wouldn't really recommend it and the syntax is quite ugly.
#include <cstdio>
template<typename T, size_t SIZE>
class Class
{
private:
T _Array[sz];
public:
Class(T (&static_array)[SIZE])
{
memcpy(_Array, static_array, sizeof(T) * SIZE);
}
};
int main()
{
char int_array[32];
Class<char, sizeof(int_array)> c = Class<char, sizeof(int_array)>(int_array);
return 0;
}
Anyways, I hope this was helpful :)
I had the same problem and I solved it this way
class example
{
int *array;
example (int size)
{
array = new int[size];
}
}
Don't you understand there is not need to use vector, if one wants to use arrays it's a matter of efficiency, e.g. less space, no copy time (in such case if handled properly there is not even need to delete the array within a destructor), etc. wichever reasons one has.
the correct answer is: (quoted)
class Class
{
int* array;
Class(int x) : array(new int[x]) {};
};
Do not try to force one to use non optimal alternatives or you'll be confusing unexperienced programmers
Instead of using a raw array, why not use a vector instead.
class SomeType {
vector<int> v;
SomeType(size_t x): v(x) {}
};
Using a vector will give you automatic leak protection in the face of an exception and many other benefits over a raw array.
Like already suggested, vector is a good choice for most cases.
Alternatively, if dynamic memory allocation is to be avoided and the maximum size is known at compile time, a custom allocator can be used together with std::vector or a library like the embedded template library can be used.
See here: https://www.etlcpp.com/home.html
Example class:
#include <etl/vector.h>
class TestDummyClass {
public:
TestDummyClass(size_t vectorSize) {
if(vectorSize < MAX_SIZE) {
testVector.resize(vectorSize);
}
}
private:
static constexpr uint8_t MAX_SIZE = 20;
etl::vector<int, MAX_SIZE> testVector;
uint8_t dummyMember = 0;
};
You can't do it in C++ - use a std::vector instead:
#include <vector>
struct A {
std::vector <int> vec;
A( int size ) : vec( size ) {
}
};
Declare your array as a pointer. You can initialize it in the initializer list later through through new.
Better to use vector for unknown size.
You might want to look at this question as well on variable length arrays.