I'm curious if these are zero initialized and all my pointers are 0 when I declare a fixed size array. I can say foo* arr[1000][1000] and I see that all the entries are 0..but I am not sure if this is something I can rely on or not. I could say foo* arr[1000][1000] = {} but this double array is a member variable in a class and I wouldn't want to have a double for loop in the constructor if it's not necessary...
Depends on how you allocate the array.
If it's static or global, then the contents will all be initialised to 0. If it's a local variable, then the contents won't be initialised to anything.
So since your array is a member variable, it won't be initialised to 0 automatically. However, you can initialise all the variables to zero by using the initialisation list in the constructor thusly:
struct A {
// VVV value-initialises the contents of arr
A() : arr() { }
double arr[x][y];
};
It depends on the context. If the array is defined at namespace level, then static initialization will set all pointers to null for you. If it is defined in a function scope or as a member of a class, there is no such guarantee.
Since it is a member of a class, it will not be correctly initialized, so you will need to initialize it manually. You can do so by adding arr() to the initialization list. Being pointers, you can use memset to set the whole array to 0 in a single call (which will also be as efficient as it gets), but beware, this only works for POD types.
Related
Consider an array of function pointers within a class in c++14:
class myClass {
myClass();
void (* myFunctions [5])();
}
This array will be populated in other parts of the code, and it is not guaranteed that the array will actually hold as many function pointers as it can (5 in the example). So before calling any of the functions referred to by the array i'd need to check whether the pointer I'm trying to use actually stores something. My idea was to compare the pointer against nullptr, and assume that it points to a valid function if the test fails, i.e. in some function of that class:
if(myFunctions[x] == nullptr) {
// Handle error
return;
}
// Use myFunctions[x]
I was wondering if I need to initialize the array before making that kind of speculation. How is this array initialized if I only write the above two lines of code? Can I assume something like myFunctions[x] == nullptr is true in that case? Or do I need to do an explicit initialization like the following one?
for(int i = 0; i < dimension; i++)
myFunctions[i] = nullptr;
I've found the zero initialization page on cppreference.com, but as I'm learning c++ and I'm still very unexperienced I wasn't able to understand whether this applies in my case. I've also tried to test the pointers by printing their value without assigning any function address and got 0 0 0 0 0, but I don't think the result is reliable: this program is for a microcontroller, and it's possible that the "garbage" values on the stack are all 0s since it is emptied during each code upload.
I don't think that you have to initialize the array, although I'd encourage you to do that. The reason why the array is default-initialized in your case is because you provide a constructor and do not mention the data member in the initializer list (cf. cppreference/default initialization):
Default initialization is performed in three situations:
...
3) when a base class or a non-static data member is not mentioned in a
constructor initializer list and that constructor is called.
Hence, default initialization will take place.
Anyway, in order to express that you rely on a data member to be "zero" without enforcing in other ways that non-initialized entries will not be accessed, I'd make the initialization explicit, e.g.
class myClass {
myClass();
void (* myFunctions [5])() = { };
}
I am quite new to C++ so forgive me, if the mistake is stupid. I am currently working on a class, that can save single characters (only one of each) and do some simple operations.
The problem I am having seems to be in the constructor of the class. Since I only have characters I am using a bool array of the size 256. So if I wanted to add the character "A" to my array I would simply flip array[64] to 1.
To use the array in the way I want to I initialized it with zeros for every index. So it looks like this:
Set<char>::Set() {
bool _elements[256] = {0};
}
If I check all the values of the member variable _elements now it does not only contain zeros. I don't know what might be causing this. There are no other function calls or anything in between.
Set set;
for (int i = 0; i < 256; i++) { printf("%d\n", set._elemens[i]; }
You're initializing a local variable _elements inside the constructor, it will be destroyed when get out of the constructor, and has nothing to do with the member variable _elemens. (And note the name is not same.)
You can initialize the member variable by member initializer list:
Set<char>::Set() : _elemens {0} {}
or in-class brace-or-equal initializer (I don't know how Set is declared so just as an example):
struct Set {
bool _elemens[256] = {0};
};
And as #M.M pointed, for both cases just {} would work well (all of the elements will be set to false) and be preferable for your case.
The array _elements is a local variable to Set() constructor. You're not supposed to be able to access it outside the Set() constructor.
The way you want to use it, you need the _elements to be a public member variable to class Set.
I have an array of structs -
struct MagicalUnicornBullets {
PS2Sprite SparklyUnicornBullet();
bool onscreen;
};
MagicalUnicornBullets MagicalUnicornBullets[25];
I want to loop through the array, and initialise the contents of the struct.
Obviously, this is just the case of a for loop, and for the bool it's simply onscreen = false; but how would I initialise the SparklyUnicornBullet?
Right now my code is -
MagicalUnicornBullets[i].SparklyUnicornBullet.ScaleAbsolute(4,4);
I'm well aware this is wrong - but how do I access the class functions when they're within the Struct?
Realize that SparklyUnicornBullet is actually a member function which returns a PS2Sprite object. This returned PS2Sprite has a member function ScaleAbsolute which you want to call. So your code above is nearly correct. You are simply missing ()'s:
MagicalUnicornBullets[i].SparklyUnicornBullet().ScaleAbsolute(4,4);
That said, there's a number of things that's bad with your code. For one, you are declaring an array that has the same name as an object:
MagicalUnicornBullets MagicalUnicornBullets[25];
I think this is allowed, but it is so evil and malmotivated that I can't even say that for certian, because I would reject any such code regardless of it's motivation or legality. You should give the array a different name:
MagicalUnicornBullets bullets[25];
Next, your initialization loop is unneeded. The code:
MagicalUnicornBullets MagicalUnicornBullets[25];
creates a C-style array of 25 MagicalUnicornBullets by calling each one's default constructor. So the easiest thing to do is to simply provide a default constructor that does what you want:
struct MagicalUnicornBullets {
MagicalUnicornBullets();
// ...
};
MagicalUnicornBullets::MagicalUnicornBullets()
: onscreen(false)
{
SparklyUnicornBullet().ScaleAbsolute(4,4)
}
Now there's no need for a loop at all. All 25 will be constructed and initialized the way you want.
Finally, usually in C++ it's advantagerous to not use a C-style array at all, but a collection class such as std::vector.
I am aware you cannot use an initialiser list for an array. However I have heard of ways that you can set an array of pointers to NULL in a way that is similar to an initialiser list.
I am not certain how this is done. I have heard that a pointer is set to NULL by default, though I do not know if this is guaranteed/ in the C++ standard. I am also not sure if initialising through the new operator compared to normal allocation can make a difference too.
Edit: I mean to do this in a header file/constructor initialisation list. I do not want to put it in the constructor, and I do not want to use a Vector.
In order to set an array of pointers to nulls in constructor initializer list, you can use the () initializer
struct S {
int *a[100];
S() : a() {
// `a` contains null pointers
}
};
Unfortunately, in the current version of the language the () initializer is the only initializer that you can use with an array member in the constructor initializer list. But apparently this is what you need in your case.
The () has the same effect on arrays allocated with new[]
int **a = new int*[100]();
// `a[i]` contains null pointers
In other contexts you can use the {} aggregate initializer to achieve the same effect
int *a[100] = {};
// `a` contains null pointers
Note that there's absolutely no need to squeeze a 0 or a NULL between the {}. The empty pair of {} will do just fine.
Normally an array will not be initialised by default, but if you initialise one or more elements explicitly then any remaining elements will be automatically initialised to 0. Since 0 and NULL are equivalent you can therefore initialise an array of pointers to NULL like this:
float * foo[42] = { NULL }; // init array of pointers to NULL
You can switch from array to std::vector and use
std::vector<T*> v(SIZE);
The values will be initialized by NULLs automatically. This is the preferred C++ way.
Update: Since C++11, there is one more way: using
std::array<T*, SIZE> array = {};
This behaves more like a corrected version of C-style array (in particular, avoids dynamic allocations), carries its size around and doesn't decay to a pointer. The size, however, needs to be known at compile time.
I am not certain how this is done. I have heard that a pointer is set to NULL by default, though I do not know if this is guaranteed/ in the C++ standard.
It is not guaranteed by the C++ standard. Built in types ( like pointers ) are filled with garbage unless set otherwise.
I am also not sure if initialising through the new operator compared to normal allocation can make a difference too.
What do you mean by "normal allocation" ? If you're talking about an automatic variable, then you can do this:
MyType * pointers[2] = {}
and the pointers should be initialized to NULL.
void* p[10] = { 0 };
If you have a member array then there is no way to initialize, unless it's a static member. If the array isn't a static member then you'll have to fill it inside the constructor's body.
That said, chances are you're really better off using a std::vector. Other than for technical reasons such as unavailability of a standard STL for your platform, or the slightly lesser performance a std::vector is better than an array by any and all criteria. If performance is the issue then make sure you profiled and know by numbers that it is an issue.
I have a question about the default initialization in C++. I was told the non-POD object will be initialized automatically. But I am confused by the code below.
Why when I use a pointer, the variable i is initialized to 0, however, when I declare a local variable, it's not. I am using g++ as the compiler.
class INT {
public: int i;
};
int main () {
INT* myint1 = new INT;
INT myint2;
cout<<"myint1.i is "<<myint1->i<<endl;
cout<<"myint2.i is "<<myint2.i<<endl;
return 0;
}
The output is
myint1.i is 0
myint2.i is -1078649848
You need to declare a c'tor in INT and force 'i' to a well-defined value.
class INT {
public:
INT() : i(0) {}
...
};
i is still a POD, and is thus not initialized by default. It doesn't make a difference whether you allocate on the stack or from the heap - in both cases, the value if i is undefined.
in both cases its not initialized, you were just lucky to get 0 in the first one
It depends on the compiler. The big difference here is that a pointer set to new Something refers to some area of memory in heap, while local variables are stored on the stack. Perhaps your compiler zeroes heap memory but doesn't bother zeroing stack memory; either way, you can't count on either method zeroing your memory. You should use something like ZeroMemory in Win32 or memset from the C standard libraries to zero your memory, or set i = 0 in the constructor of INT.
For a class or struct-type, if you don't tell it which constructor to use when defining a variable, then the default constructor is called. If you didn't define a default constructor, then the compiler creates one for you. If the type is not a class (or struct) type, then it is not initialized since it won't have a constructor, let alone a default constructor (so no built-in types like int will ever be default-initialized).
So, in your example, both myint1 and myint2 are default constructed with the default constuctor that the compiler declared for INT. But since that won't initialize any non-class/struct variables in an INT, the i member variable of INT is not initialized.
If you want i to be initialized, you need to write a default constructor for INT which initializes it.
Firstly, your class INT is POD.
Secondly, when something is "initialized automatically" (for automatic or dynamic objects), it means that the constructor is called automatically. There is no other "automatic" initialization scenario (for automatic or dynamic objects); all other scenarios require a "manually" specified initializer. However, if the constructor does not do anything to perform the desired initialization, then that initialization will not take place. It is your responsibility to write that constructor, when necessary.
In both cases in your example you should get garbage in your objects. The 0 that you observe in case of new-ed object is there purely by accident.
That's true for non-POD object's but your object is POD since it has no user defined constructor and only contains PODs itself.
We just had this topic, you can find some explinations here.
If you add more variables to the class, you will end up with non-initialized member variables.