Reputation: 1687
I have the following piece of code which after running throws error :
class arr2{
int count;
public:
int elem[5];
arr2()
{
count=-1;
elem[5]=(0,0,0,0,0); //{} throws error i dont know why
}
};
int main()
{
arr2 obj;
vector<int> vec;
vec.assign(10,42);
vector<int> ::iterator itr=vec.begin();
for(;itr!=vec.end();++itr){
cout<<*itr<<endl;
}
return 0;
}
ERROR stack around the variable 'obj' was corrupted.
If i remove arr2 obj;
then it works fine.
Is there anything wrong with the class itself or the statement in ctor elem[5]=(0,0,0,0,0);
I tried to define an array in main with {} and it works fine. I dont know why it fails when inside class.
int arr4[4]={1,2,3,4}; //OK
Upvotes: 0
Views: 486
Reputation: 385325
You need to consider that there are two distinct constructs at work here.
// initialiser
// |
// name ("elem") |
// | |
// ▼▼▼▼ ▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼
int elem[5] = {0, 0, 0, 0, 0};
// ▲▲▲ ▲▲▲
// \ /
// \ /
// \ /
// type (int[5])
// new element value
// |
// name ("elem") |
// | |
// ▼▼▼▼ ▼▼▼▼▼
elem[n] = 12345;
// ▲▲▲ ▲
// | |
// | assignment operator
// |
// index (n)
Your problem has nothing to do with whether you write your code in main
or in a class definition; the problem is that you are trying to write an assignment as if it were an initialisation.
{0, 0, 0, 0, 0}
simply cannot be used in an assignmentelem[5]
instead of int elem[5]
, you're naming the 6th element of elem
, not declaring a new array of size 5 called elem
.The error goes away when you use (0, 0, 0, 0, 0)
instead, because this is an expression that evaluates to 0
, and you can assign 0
to an element of an int
array.
Unfortunately, you're doing so to an element that does not exist, because elem[5]
is out of bounds. It's a hypothetical sixth element in a five-element array.
The inability to use initialiser syntax to assign to all of an array's elements in one fell swoop is a limitation of C and C++.
To assign to the array at an arbitrary place, you'd have to assign them one by one in a loop, or use a fill function:
std::fill(std::begin(elem), std::end(elem), 0);
…which is much better anyway.
Fortunately, you've committed another crime that's actually quite convenient: you actually do want to initialise, even though at the moment you're instead assigning inside the constructor body. To initialise class members, you must use the constructor's member-initialiser list and, as it happens, the constructor's member-initialiser list enables us to use initialiser syntax:
arr2()
: elem{0, 0, 0, 0, 0}
{}
…or, more simply:
arr2()
: elem{}
{}
Upvotes: 2
Reputation: 2457
int elem[5]; // Represents that the array is of size 5
Since array index starts with 0, the available array indices are:
elem[0]
elem[1]
elem[2]
elem[3]
elem[4]
(total five elements)
elem[5]
is out of bounds.
Upvotes: 3
Reputation: 484
elem[5]=(0,0,0,0,0); //{} throws error i dont know why
using {} throws error because, {} have to be used only for initialization of array, not for assignment.
Also above statement is not assigning all your array elements to zero, instead it tries to assign one zero to elem[5], which is actually out of boundary of your array. your array starts at elem[0] and ends at elem[4].
elem[5] is actually refers to the address of vector defined below. vector vec;
As you are corrupting this memory. You got exception.
Upvotes: 0
Reputation: 409432
The assignment
elem[5]=(0,0,0,0,0);
write a single zero (read about the comma operator) at the sixth place in the array (remember that array indexes are zero-based), which is one beyond the end of the array. Writing beyond the bounds of an array leads to undefined behavior.
There are a few ways to initialize the array, the simplest being a constructor initializer list:
class arr2
{
int elem[5];
public:
arr2()
: elem{}
{}
};
The above will value-initialize the array, which means that each element in the array also will be value-initialized, and for an int
value-initialization will set it to 0
.
To expand on the error you get, just about all systems and compilers today store local variables on the stack, that includes the variable obj
in your main
function. Placing an object on the stack also places its member variables on the stack. If you write out of bounds of the array, then you also write on stack-memory you do not own the right to, and therefore corrupt the stack.
Upvotes: 2
Reputation: 5854
This does not do what you expect:
elem[5]=(0,0,0,0,0);
You assign the element at index 5
(which is out of bounds) the value 0. You do not assign an initializer list, but rather a series of zeroes with the comma operator in between (which returns the second value of each call), which in turn returns the rightmost zero.
Upvotes: 0