5
int letters[] = {['A'] = 4, ['B'] = 8, ['E'] = 3, ['I'] = 1, ['O'] = 0, ['S'] = 5};

When I initialize the array letters above, my assumption is that at the index of each capital letter, the value will be the number i.e. if ['A'] = 4, then at index 'A' the value will be 4 and the rest of the values not initialized will be 0 by default.

But when I print all the values of the array letters, I am getting this output:

00000000000000000000000000000000000000000000000000000000000000000480030001000000000514303876720941309621-1392458268143038767232767-197939865932767-1979398659327670010143038792832767

I have no idea where the negative numbers are coming from.

Cristian Ciupitu
  • 20,270
  • 7
  • 50
  • 76
user2635911
  • 472
  • 2
  • 6
  • 16
  • How are you printing all of the values? – Sean Bright Jun 20 '14 at 21:01
  • possible duplicate of [How to initialize an array in C](http://stackoverflow.com/questions/201101/how-to-initialize-an-array-in-c) – Natan Streppel Jun 20 '14 at 21:02
  • This does not seem like a duplicate to me. The OP knows that they want to use designated initialization and seems to have a correct understanding of the [standard](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf) (C99 6.7.8, par 21). The issue here seems to be with the way it's being output (and possibly a misunderstanding of paragraph 22). – laindir Jun 20 '14 at 21:21
  • 1
    Voted up for having learned something about something as basic as array initialization. – Utkan Gezer Jun 20 '14 at 21:21

3 Answers3

9

'S' is the highest index you gave a value for and, as your encoding's apparently ASCII, the length of your array is 83 (= 0x53). Everything with smaller indexes (without an initializer) is initialized to 0.

When you print your array, you are accessing the array out-of-bounds, which is undefined behavior.

What your program probably outputs are the values which happen to be on the stack after your array. However, as said above, there is no guarantee about what will happen.

HTH

mafso
  • 5,433
  • 2
  • 19
  • 40
  • It's not undefined - you just get whatever happened to be in memory there. This is how buffer overflow attacks work. Actually, I believe this was exactly how Heartbleed worked... – amo Jun 20 '14 at 21:06
  • 6
    @amo, It's undefined behaviour per the standard. Anything is allowed to happen. Nothing is required to happen. – chris Jun 20 '14 at 21:06
  • 1
    @amo; You're right in that it often does, in fact, work. But still, it is UB. – mafso Jun 20 '14 at 21:07
  • @chris, true. I was addressing the OP's question "I have no idea where the negative numbers are coming from." – amo Jun 20 '14 at 21:10
7

My guess is that the code you wrote to print the array is wrong. Just tested with this:

#include <stdio.h>

int main()
{
  int letters[] = {['A'] = 4, ['B'] = 8, ['E'] = 3, ['I'] = 1, ['O'] = 0, ['S'] = 5};
  int i;

  for (i = 0; i <= 'S'; i++) {
    printf("%d\n", letters[i]);
  }

  return 0;
}

And it works fine and prints everything up to and including 5.

Sean Bright
  • 118,630
  • 17
  • 138
  • 146
  • 1
    Yep I am an idiot. When I printed the values using a for loop, I used to condition i < 100 instead of i <= 'S' – user2635911 Jun 20 '14 at 23:16
2

You most probably are using a for loop that is structured as follows:

for ( int i = 0; i < sizeof letters; i++ ) {
    // ...
}

And the problem lies within the sizeof letters part, which gives you the size of... letters, which is not how many elements the array has. It rather is, the size of letters, that is, size of a single element times amount of elements:

sizeof letters == sizeof * letters * amountofelements;
// evaluates to 1
// assuming that amountofelements is the amount of elements that
// the array letters points to

// more: sizeof * letters is equivalent to sizeof( letters[0] )
// and the equation above is equivalent to
// sizeof( letters ) == sizeof( letters[0] ) * amountofelements;
// just in case...

So, change your for condition into the following:

for ( int i = 0; i < sizeof letters / sizeof * letters; i++ ) {
    // whatever
}

Thanks for giving me the opportunity to use my psychic powers, kek.

Utkan Gezer
  • 3,009
  • 2
  • 16
  • 29
  • Nice observation about how this could have happened, indeed! But I'm not fully convinced… We have 181 characters of output, 2 of which are `-`, so 179 `int`s at maximum (unfortunately, there is no space or anything between the numbers), which would imply 2-byte integers (or at least, narrower than 4 bytes). @user2635911: Is this the case? – mafso Jun 20 '14 at 21:39
  • @mafso It was just a guess really. I have realized that there aren't even enough many for that output to happen on a setup with `sizeof( int ) == 4`, as in mine, only after having posted this answer. My point was, the problem lies within his/her loop, and we have to be psychics to spot it until loop structure is provided to us. – Utkan Gezer Jun 20 '14 at 21:49
  • ACK; when I wrote my answer, I was wondering how this output actually was generated and had no idea at all (besides the fact, that there is obviously some out-of-bounds access) and just thought that this is a very plausible shoot in the dark when I read your answer. And 2-byte integers are possible and do exist, so I don't say you're wrong, I just want to know if you're right (but this question is addressing OP, not you, we can't know what she did). – mafso Jun 20 '14 at 21:56