-5

When declaring a char array of length n, the value at [n] always is 0. Shouldn't it be a garbage value?

Code

#include <stdio.h>

int main() {
    char arr[3];
    arr[0] = 'a'; arr[1] = 'b'; arr[2] = 'c';
    // Here arr[3] can be any garbage value.
    // But it always appears to be 0. Why?

    // Also arr[4], arr[5], arr[6]... are not 0,
    // just some garbage as expected

    printf("i\tch  ascii\n");
    int i;

    for(i = 0; arr[i] != 0; i++) //Always breaks at i=3
        printf("%d\t%c\t%d\n", i, arr[i], (int) arr[i]);
    int more = i + 5;
    for(; i<more; i++)
        // I am intentionally going outside the bound
        printf("%i\t%c\t%d\n", i, arr[i], (int) arr[i]);
    return 0;
}

Expected output

What do you think the output will be? You may assume :

i   ch  ascii
0   a   97
1   b   98
2   c   99
3   N   78  ----> (This may or may not be 0)
4   �   -103
5   N   78
6   �   -125
7   �   -100

Actual output

i   ch  ascii
0   a   97
1   b   98
2   c   99
3       0  ----> (Why is this always 0?)
4   �   -103
5   N   78
6   �   -125
7   �   -100

Note: This does not happen with int/double/float arrays.

Rahat Zaman
  • 1,322
  • 14
  • 32
  • Did you suppose to write `ara[i]!='\0'` instead of `i!='\0'`? – Sergey Nov 09 '16 at 07:11
  • 1
    A matter of coincidence. – barak manos Nov 09 '16 at 07:22
  • Thought experiment: take a deck of cards and toss them all over the floor. Set down your foot on one card. Lift your foot and see what it is. Put your foot down on the card again. Would you be surprised if you saw the same card the next time you lifted your foot? – molbdnilo Nov 09 '16 at 10:43

3 Answers3

1

You don't have a null terminator inside your array. printf reads past its end. That is undefined behavior by the c++ standard. It ends in ara[4] because you are (un)lucky. It can go further or even crash you program, because what it should do is undefined.

To possibly rationalize the stop at ara[4]: There is probably a \0 character at that location past your buffer

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • Ending at `ara[4]` is not so much of luck, as it could theoretically be outside the region of mapped memory (i.e., result in a bus-fault). The luck, perhaps, is in the fact that no memory access violations occurs as a result of reading `ara[4]` (or perhaps it's in fact not so fortunate, as one does not become aware of the problem immediately thereafter, leaving themselves to the mercy of the gods of debug sessions). – barak manos Nov 09 '16 at 07:26
  • @barakmanos, I doubt it could end up outside of the mapped memory region. There is the data kept by the hosted environment on the stack frame to consider. But yes, "working" rather than crash & burning is unlucky. – StoryTeller - Unslander Monica Nov 09 '16 at 07:29
  • "the data kept by the hosted environment on the stack frame to consider" - that's platform specific (and in any case, not something dictated by the language standard). For example, suppose you're running on bare-metal (i.e., no OS, no virtual memory, no threads and no processes), and it just so happen that this array is allocated at the end of the stack at the point in time when the function is called. BTW, this array may well be allocated in the data section, not in the stack (i.e., global and or static). OP doesn't specify that fact. But again, this is not dictated by the language standard. – barak manos Nov 09 '16 at 07:33
  • @barakmanos, Rationalizing UB is an exercise in futility. So I reworded it with less assumptions about the OPs code. Any one of your points or my original explanation can be true. – StoryTeller - Unslander Monica Nov 09 '16 at 07:38
  • I wasn't trying to rationalize it. I merely implied that by "It ends in `ara[4]` because you are lucky", you were in fact trying to rationalize it yourself, since there is not much luck in that. In any case, I guess that this is more of a philosophical debate, so... – barak manos Nov 09 '16 at 07:49
  • @barakmanos, well I admitted to trying to rationalize it. Regardless, I think my latest edit covers all bases :) – StoryTeller - Unslander Monica Nov 09 '16 at 07:51
0

How you you expect to i=='\0' simply iterate up to array size or compare a character value to '\0'. The random indexes you are getting because of garbage values in memory.

Ali Kazmi
  • 1,460
  • 9
  • 22
0

It's quite likely that your implementation lays out the local variables as

  • ara - 3 bytes
  • padding - 1 byte
  • i (or some other local variable).

So when you reach the end of ara and get into Undefined Behaviour, the outcome is still fairly deterministic (but subject to change if you use a different compiler).

Toby Speight
  • 27,591
  • 48
  • 66
  • 103