4
#include <stdio.h>

int main(void) {
    int memo[1000];
    for (int i = 0; i < 1000; i++) {
        printf("%d\t", memo[i]);
    }
    return 0;
}

I thought everything should be initialized to 0 but it is not. Is there any reason for this? Thank you so much for your help.

Boann
  • 48,794
  • 16
  • 117
  • 146
Kang
  • 49
  • 4
  • 2
    Do you believe that your code should print all zeroes and are confused why it doesn't (it's undefined behavior)? Or are you asking why the C standard doesn't guarantee zero-initialization? In any case, `int memo[1000] = {0};` will initialize the array to all zero fyi – Ryan Haining Apr 25 '21 at 17:38
  • If you use just 1 value for initialization (`int memo[1000] = {-1};`), all the other elements will be initialized with `0`; if you don't initialize all elements contain *garbage*. – pmg Apr 25 '21 at 17:38
  • 2
    [this answer](https://stackoverflow.com/a/6212973/1013719) has a lot of information for you – Ryan Haining Apr 25 '21 at 17:40
  • Zero init by default exist for global or `static` arrays. Move definition before `main` and it will be initialized. – i486 Apr 25 '21 at 17:40
  • The reason is largely historical, and compatibility with past practices and old compilers. You could join the C standardization group and lobby for an evolution of the C standard. Read [n1570](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) or something newer. Contribute to write a better future C standard. – Basile Starynkevitch Apr 25 '21 at 17:44
  • There was another *exact* question cannot find it, but I do not think question marked as duplicate of this one, is actually not duplicate because of this: *I thought everything should be initialized to 0 but they are not. Is there any reason for it?* The other question deals with how to do it, but not why is it done this way. –  Apr 25 '21 at 18:41

3 Answers3

4

Objects defined locally with automatic storage in a function body are uninitialized in C. The values can be anything, including trap values on some architectures that would cause undefined behavior just by reading them.

You can initialize this array as int memo[1000] = { 0 };. The first element is explicitly initialized to 0, and all the remaining ones will also initialized to 0 because any element for which the initializer is missing will be set to 0.

For completeness, int memo[1000] = { 42 }; will have its first element set to 42 and all remaining ones to 0. Similarly, the C99 initializer int memo[1000] = { [42] = 1 }; will have its 43rd element set to 1 and all others set to 0.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • 1
    @CEPB: It's fun to learn something new everyday! – chqrlie Apr 25 '21 at 18:00
  • So was this `int memo[1000] = { 0 };` introduced in ANSI C? –  Apr 25 '21 at 18:02
  • 2
    @CEPB: Yes, K&R C didn't allow auto arrays to be initialized (see K&R I page 83). This was roughly in keeping with the philosophy that every line of code should be O(1) (e.g. you couldn't assign structs or pass them by value either, because this might require copying arbitrarily large blocks of memory). C89 footnote 65 explicitly noted that the ability to initialize all auto objects was new. – Nate Eldredge Apr 25 '21 at 18:12
  • damn I only have K&R ANSI C. tnx for your point @NateEldredge –  Apr 25 '21 at 18:16
  • @CEPB: Note I am talking about K&R's first edition, which predates ANSI C. Their second edition covers ANSI C, also known as C89, in which these initializers are allowed. I'm not sure from your comment which of the two is supported by your compiler, but I'll be extremely surprised if it doesn't support C89, unless you are doing retrocomputing for some ancient machine. – Nate Eldredge Apr 25 '21 at 18:17
  • @CEPB: To go back to the early days of C, here is a link to Dennis Ritchie's C Manual from 1974: https://www.bell-labs.com/usr/dmr/www/cman.pdf . Page 16 explains initializers, that were only allowed for *external* data and was deemed *incomplete and machine-dependent* for structures. See also this tutorial: https://www.lysator.liu.se/c/bwk-tutor.html – chqrlie Apr 25 '21 at 18:30
  • I cannot find mention of `{0}` in `K&R ANSI C` either. –  Apr 25 '21 at 18:32
  • @CEFB: Read **A8.7 Initialization** page 219. The syntax `int memo[1000] = { 0 };` is supported, `0` initializes the first member of the array and if the initializer has fewer expressions than the number of members of the array, the trailing members are initialized with `0`. (notice how we now use elements for arrays instead of members). K&R did not specify that `= { 0 }` is a generic initializer, adequate for all types, nor was it common place to use it as such. – chqrlie Apr 25 '21 at 18:48
3

In C, when you do

int memo[1000];

you are allocating 1000 little spots in memory. Those spots may or may not currently hold some garbage data already. So it is often considered good practice to initialize all your variables. It will make debugging easier.

You can replace the above line with,

int memo[1000] = {0};

to initialize every element of the array to be 0;

Edit: There are definitely deeper reasons for the behaviour you're experiencing, as talked about by the other answers here. But, if you are a beginner to C or programming in general. This is sufficient for you to start using arrays with initialization without being overwhelmed by more complicated details. If you are more advanced then please defer to the other answers.

  • As explained in an answer on a similar question, I don't think it's that easy: https://stackoverflow.com/questions/27270020/how-to-use-default-values-in-a-char-array – Dominique Apr 25 '21 at 17:56
  • 2
    @Dominique: there is no difficulty here, `int memo[1000] = {0};` will cause `memo` to have all its elements set to `0`. As explained in the other question, there is no portable shortcut syntax to initialize all elements to a different value, but **gcc** supports `int memo[1000] = { [0 ... 999] = 42 };` to initialize all elements to `42`. – chqrlie Apr 25 '21 at 18:05
1

From the C Standard (6.7.9 Initialization)

10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static or thread storage duration is not initialized explicitly, then:

— if it has pointer type, it is initialized to a null pointer;

— if it has arithmetic type, it is initialized to (positive or unsigned) zero;

— if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;

— if it is a union, the first named member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;

and

19 ... all subobjects that are not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration.

Thus in this program

#include <stdio.h>

int main(void) {
    int memo[1000];
    for (int i = 0; i < 1000; i++) {
        printf("%d\t", memo[i]);
    }
    return 0;
}

the array memo has the automatic storage duration and according to the provided quote from the C Standard its elements have indeterminate values.

You could declare the array like

    int memo[1000] = { 0 };

In this case the first element of the array is explicitly initialized by 0 and all other elements are implicitly initialized also by 0.

You could select any element of the array to be explicitly initialized like for example

    int memo[1000] = { [999] = 0 };

If you would write

#include <stdio.h>

int memo[1000];

int main(void) {
    for (int i = 0; i < 1000; i++) {
        printf("%d\t", memo[i]);
    }
    return 0;
}

or

#include <stdio.h>

int main(void) {
    static int memo[1000];
    for (int i = 0; i < 1000; i++) {
        printf("%d\t", memo[i]);
    }
    return 0;
}

then elements of the array will be zero-initialized because a variable declared in a file scope or with the storage specifier static has the static storage duration.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335