3

Doesn't the array when declared in a loop sets to zero when the loop repeats?

I have an array and working with it this way..

while(i<n)
{
    int a[1000];
    //taking inputs in array..
    /*some calculations with array..
    the values in array may change*/
}

The next time when the loop repeats, array a is declared again, it is a new array, so aren't values in array zero now?

Actually I have a made a code this way and observed that the values are not zero but instead are same as they were just before the loop repeats. Why?

vinay_Kumar
  • 117
  • 2
  • 10
  • 4
    In general, C does not initialize anything; it's probably just pointing to the same memory locations. You have to initialize the array yourself. See http://stackoverflow.com/questions/201101/how-to-initialize-an-array-in-c – Robert Harvey Jul 29 '14 at 17:08
  • If you don't explicitly initialise the array, then the second time around the loop, they it may well contain what was left at the end of the first loop -- for if not, some code would have had to have been added to change it ! However, the standard (C99) says that "the value becomes indeterminate each time the declaration is reached" -- noting that this allows the compiler to overlay one local variable over another, where it can work out that they are never required at the same time. –  Jul 29 '14 at 17:28
  • As a note to the people expecting the array to "generally" be the same (lots of them in this thread, wtf?), think of the most basic optimization of loop unrolling. While it probably won't be done for a 1k array, if it was smaller it would probably generate a new array on the stack for each unroll. – Blindy Jul 29 '14 at 19:05

3 Answers3

3

The values of the array are uninitialized, they contain the "random" junk values that were on the stack.

Also the numbers in the array might be overwritten in each loop run. I.e. if you need the values to stay unaltered between the loops, then hoist the array declaration before the while loop.

Use

int a[1000] = {0};

to initialized the array with zeros.

Kijewski
  • 25,517
  • 12
  • 101
  • 143
  • 2
    It's not "initialized with undefined values". It's just not initialized, i.e., no action occurs at all. – James Curran Jul 29 '14 at 17:11
  • 1
    Subleties of the English language. "Initialized" (particularly the "ize" suffix), implies a process doing something. So saying "initialized ... in each loop" means that the current values of the array will be replaced by something else. – James Curran Jul 29 '14 at 17:15
3

Local arrays are not automatically zero'd, even on first use.

You would need to explicitly do it:

while(i<n)
{
    int a[1000] = {0};
    // :
}
James Curran
  • 101,701
  • 37
  • 181
  • 258
  • 1
    Will the arrays be initialized to zero in C++? – vinay_Kumar Aug 03 '14 at 05:37
  • 1
    In both C & C++, there is no requirement the an array be initialized by default. Often, for a global array, the library startup code will zero the array, but local arrays never are. – James Curran Aug 04 '14 at 14:01
1

In principle, it should be treated as a new array every time. In practice, it is likely to carry the same values as it did in the previous iteration. If you wanted a completely new array every time the loop went round, you'd need to use malloc or calloc to allocate it1 (then free at the bottom of the loop to avoid memory leaks).

Consider this test:

#include <stdio.h>

int main()
{
    int i = 0, n = 10;
    while(i++<n)
    {
        int a[10];
        printf("before assignment: %d\n", a[2]);
        a[2] = 5;
    }
    return 0;
}

On the first iteration, a[2] could contain anything. In fact, reading the value before it is initialised is undefined behaviour. This is certainly something to be avoided, as it can lead to unpredictable consequences.

On the second iteration (and subsequent ones) it happened to contain 5 when I tested it (but there's no guarantee that it should).

If however, you initialised a like this:

int a[10] = {0};

then all the elements of a would be 0 each time.

1. Actually in practice, you may well end up with the same block of memory if you did this anyway. The behaviour is not to be relied upon either way.

Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
  • Good chances that you always get the same memory block if you use `while (…) { malloc(); …; free(); }`. – Kijewski Jul 29 '14 at 17:19
  • 3
    Reading an uninitialized value is UB. The compiler may e.g. optimize the whole loop out because it may assume it is never entered. – mafso Jul 29 '14 at 17:22
  • 1
    Unless I have learned it all wrong, it **is** a new array every time. Chances are high for your computer to offer you the same memory location on each cycle, but it does not necessarily have to be. – Utkan Gezer Jul 29 '14 at 17:24
  • @mafso, funny, GCC doesn't say a thing even if I compile the above code with `gcc -Wall -Wextra -ansi -pedantic array.c` – Tom Fenech Jul 29 '14 at 17:27
  • @Kay that's fair enough, I guess that it should be _treated_ as a completely new array though (for example, in terms of initialising it before use). I've added your point as a footnote. – Tom Fenech Jul 29 '14 at 17:29
  • @ThoAppelsin would you expect the same behaviour if a simple `int` were defined as well? – Tom Fenech Jul 29 '14 at 17:31
  • @TomFenech: It even doesn't with optimizations, but replaces the `printf` call by `printf("...", 5);` (so it makes sort of use of the UB). A compiler doesn't have to complain about UB. – mafso Jul 29 '14 at 17:46
  • @mafso does that mean that the accepted answer which claims that the array is populated with random values should be amended? – Tom Fenech Jul 29 '14 at 17:48
  • @Kay. “they contain the "random" values”—As an example: I don't find the link, but I remember a code example, where an uninitialized variable multiplied by 2 was treated as odd by `gcc -O3`. A random value would at least be even after that. I think you're answer is a little misleading (although you mention the stack, so you're clearly not talking about what the standard mandates but what actually happens and why the array appeared to keep its old values, which IMO should be covered here). Maybe add a note, that you definitely shouldn't read uninitialized variables in productive code at all. – mafso Jul 29 '14 at 18:02
  • 2
    Array **is** populated with random values, on each cycle, just as on the first cycle. Maybe we should call it rather *junk* than *random*. The values are whatever there used to be in that specific memory location. On first cycle, it gives the location with some junk value in it that is unfamiliar. On the subsequent cycles, it still gives the location with some junk values in them, which are this time familiar. They still are junk values though. – Utkan Gezer Jul 29 '14 at 18:04
  • 1
    I changed it to *junk values*, that term is indeed better. – Kijewski Jul 29 '14 at 18:07
  • 4
    It's like going to a local pool to swim and being given a locker. Say you first get in at 9:00 AM, given the key to the first locker that is vacant. Say they aren't being cleaned regularly, therefore contains a *junk newspaper* inside. You take that out, put yours. You leave the pool at 9:01 AM to return back at 9:02 AM. Cutie at the desk looks at you with a weird look on her face, gives you the same key again. The locker will have your newspaper inside, but, well, she would give the keys to someone else if she had the chance. Unless you buy that locker, declare your variable outside the loop. – Utkan Gezer Jul 29 '14 at 18:15
  • @ThoAppelsin nice analogy, thanks for explaining. I've edited my answer, hopefully it is correct now. – Tom Fenech Jul 29 '14 at 18:47
  • @mafso Thanks for pointing that out to me, I've edited my answer. Please let me know if you think it requires any further modification. – Tom Fenech Jul 29 '14 at 18:47
  • 1
    Yes it does: The downvoters should retract their votes :) That aside, I'm not sure what OP actually did: Reading uninitialized values (she had to determine somehow what values where in there) in which case it should be pointed out, that this is UB; or if she (as indicated by the comments in the code given in the question) doesn't but saw the values of the array in a debugger, in which case the only misconception was, that automatic variables were initialized. Without clarification on this, I wouldn't change anything. – mafso Jul 29 '14 at 19:00