8

I've been refactoring some code and I noticed some wonky behavior involving an uninitialized int array:

int arr[ARRAY_SIZE];

I set a break-point and it seems all values default to -858993460. Is there something special with this value? Any ideas why they don't default to 0?

kbirk
  • 3,906
  • 7
  • 48
  • 72
  • You need to provide more context for this question. If these are global variables, then the runtime is supposed to initialize them to zero automatically. If they are local, then not. (Your problem is probably the latter, but it is impossible to say from your question.) – Nemo Jun 06 '11 at 01:22

6 Answers6

16

There is no "default" in C++ -- variables and array elements, until initialized by your code, will contain whatever was in memory last.

In other words, when these variables are declared, a space in memory is reserved for their use. The bits in memory left over from the last time that memory was used are still there, causing your variables to initially appear as if they're filled with "garbage". The reason that memory isn't always zeroed out right away is speed -- it takes time to zero out memory.

You can initialise your array using a loop, or use this trick (at risk of being much less readable):

int mouseBufferX[mosueBufferSize] = { 0 };

This works because when you use a list of values to initialize the array, and there's less literal values than the number of elements in the array, the remaining elements always get initialized to 0.

Cameron
  • 96,106
  • 25
  • 196
  • 225
  • 1
    If these are global variables ("static storage duration"), they are supposed to be initialized to zero automatically. See [this Q&A](http://stackoverflow.com/questions/3553559/how-are-local-and-global-variables-initialized-by-default), for instance. – Nemo Jun 06 '11 at 01:16
  • I wouldnt recommend doing that (`={0}`). I would only do this i am forced to use a char array for a string. –  Jun 06 '11 at 01:25
  • There is a "default" in C++. But what that default is depends on context, and in this context it is to do nothing at all. – Dennis Zickefoose Jun 06 '11 at 02:15
  • 1
    I think its more readable this way. But that's just me opinion. – Martin York Jun 06 '11 at 03:37
  • I regard the `= {0}` as idiomatic, actually; why do you say it's less readable? Though, it would probably deserve an explanatory comment if you were setting the first entry to a non-zero value and relying on the side-effect that the rest will be zeros. – Sumudu Fernando Jun 06 '11 at 03:45
  • @Sumudu: It's not explicit; anybody reading that and not knowing the rule about array initialization could easily miss the importance of the assignment. On the other hand, as you say, it's fairly idiomatic and common to come across. A matter of style/choice, I think :-) – Cameron Jun 06 '11 at 14:28
16

-858993460 is, in hex, CCCCCCCC, which Visual Studio puts as default in DEBUG MODE. This is to make it easier for you to notice that you forgot to initialize the variable. In release mode it could be anything.

I’m actually unsure why mouseBufferX isn’t an element of 10 items (if this does compile and that isn’t 10 elements). But I am pretty sure that the standard says statics are initialized before nonstatics. Anyways, I personally hate using defines and consts to declare ints. Use an enum instead.

C++ doesn’t default anything to 0, so you MUST assign something a value before using it. Static variables are exceptions to this rule as they are set to zero by default. But I’ll note that the use of static variables is discouraged, and some languages (such as C#) do not allow you to declare static variables in a function.

Rory O'Kane
  • 29,210
  • 11
  • 96
  • 131
  • Do you have any particular reason to dislike const ints, or is it just because you heard somewhere once that enums were better? – Dennis Zickefoose Jun 06 '11 at 02:17
  • 4
    @Dennis: enum constants are rvalues, and they are guaranteed not to consume memory. – fredoverflow Jun 06 '11 at 08:51
  • 1
    @Dennis: i avoid macros. It always felt silly to me to use them as constants. I'd either make them look like macros (SOME_CONST_VAR) which looks awkward in code and if i dont do this it may clobber a variable, function etc (why macros/define tend to be avoided). The other option is `const int blah=val` but if i dont need a memory address (which i'd do &blah to) which is 99.9999% of the time why bother writing all that out. enum lets you define it easily. Also this goes without saying initialize order and if it static or not –  Jun 06 '11 at 12:12
  • Also i am pretty sure i did something like `const int var = A/C*100+somethingelse` and there was an error which it silently hide hid from me. I dont remember what it was but i do remember it back in VC6 so i am sure it doesnt apply anymore but when i changed it to an enum i got a compile time error instead of a weird int value bc a warning/error was hidden away. Also what fred said. ints MUST consume memory (thus you can take their address, reference in plugins, etc) where enums are inlined –  Jun 06 '11 at 12:15
  • The memory concern seems spurious; it is only applicable to integral constants, and at namespace scope at least memory generally won't be specially allocated. But I don't really care what your reason was, just wanted you to back your advice up. – Dennis Zickefoose Jun 06 '11 at 13:56
  • [When and why will an OS initialise memory to 0xCD, 0xDD, etc. on malloc/free/new/delete?](https://stackoverflow.com/q/370195/995714) – phuclv Aug 18 '18 at 11:13
2

You need to explicitly set the values for the array - they do not "default" to anything. Try:

memset(mouseBufferX,0,sizeof(mouseBufferX));

//or 

int mouseBufferX[mouseBufferSize] = {0};

//and, in C++ this *might* work too (fuzzy memory!):

int mouseBufferX[mouseBufferSize] = {};
Zabba
  • 64,285
  • 47
  • 179
  • 207
2

C++ doesn't initialize variables. When a chunk of memory is allocated for the variable, that chunk of memory is left as-is and contains the value it did when it was allocated.

However, some compilers (like g++, I believe) will automatically initialize things to 0 - but don't depend on this behaviour as it will make your code less portable.

To get an array to have all the values in it initialized to a value, you can do this:

int mouseBufferX[mouseBufferSize] = {0};

int mouseBufferY[mouseBufferSize] = {0};

You can provide as many values as you want in the initialization list and the elements will be assigned those values.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
0

Sometimes in a debug build, the compiler will initialize memory to a known value to make it easier to detect bugs. If your compiler does this, it should be documented somewhere.

This is entirely at the discretion of the compiler, because the standard doesn't guarantee any initialization whatsoever in this case.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • Last time I used VC++ it did this (caused some interesting behaviour when I switched to release ;-)) – Cameron Jun 06 '11 at 01:21
0

thats a really dangerous assumption your making.

on a good compiler you might get a constant default value like the closest to -infinity(edit: or 0xCCCCCCCC thx acidezombie24), otherwise you'll just get random numbers

ALWAYS initialize your variables

something like

static const int mouseBufferSize = 10;
int mouseBufferX[mouseBufferSize];
memset(mouseBufferX,0,sizeof(mouseBufferX));
int mouseBufferY[mouseBufferSize];
memset(mouseBufferY,0,sizeof(mouseBufferY));
Jason Rogers
  • 19,194
  • 27
  • 79
  • 112