0

I have a simple code in C to see if three same char arrays all end with '\0':

int main(){
    char a[4] = "1234";
    char b[4] = "1234";
    char c[4] = "1234";


    if(a[4] == '\0')
            printf("a end with '\\0'\n");
    if(b[4] == '\0')
            printf("b end with '\\0'\n");
    if(c[4] == '\0')
            printf("c end with '\\0'\n");

    return 0;
}

But the output shows that only array b ends with terminator '\0'. Why is that? I supposed all char arrays have to end with '\0'.

Output:

b end with '\0'

msc
  • 33,420
  • 29
  • 119
  • 214
Tony Chen
  • 207
  • 2
  • 13
  • 4
    You declared the arrays with space for 4 bytes, but you’re trying to read byte 5. – Ry- Jul 17 '17 at 07:48
  • 1
    Buy a good beginners book. When you do all the exercises in it, you can start to look for the errors in the compiler :D – 0___________ Jul 17 '17 at 07:51
  • 1
    "I supposed all `char` arrays have to end with `'\0'`."-- Nope. All _strings_ must end with a `\0` terminator, but character arrays without the null-terminator are perfectly acceptable. – ad absurdum Jul 17 '17 at 07:51
  • @DavidBowling but is it okay to initialize the 4 sized char array with a 5 sized char array? – Ajay Brahmakshatriya Jul 17 '17 at 08:07
  • 1
    @AjayBrahmakshatriya-- well, you can't initialize an array with another array; you initialize with a string literal or with an initializer list. Extra elements in the initializer are ignored, so the result of using `char a[4] = "1234";` is that `a` is a character array (as declared) initialized with values from the string literal, but not a _string_. – ad absurdum Jul 17 '17 at 08:14

4 Answers4

6

The major problem is, for an array defined like char a[4] = .... (with a size of 4 elements), using if (a[4] ....) is already off-by-one and causes undefined behavior.

You want to check for a[3], as that is the last valid element.

That said, in your case, you don;t have room for null-terminator!!

Emphasizing the quote from C11, §6.7.9,

An array of character type may be initialized by a character string literal or UTF−8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.

So, you need to either

  • use an array size which has room for the null-terminator
  • or, use an array of unknown size, like char a[ ] = "1234"; where, the array size is automatically determined by the length of the supplied initializer (including the null-terminator.)
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
4

It is undefined behaviour because you have trying to access array out of bound.

Do not specify the bound of a string initialized with a string literal because the compiler will automatically allocate sufficient space for entire string literal,including the terminating null character.

C standard(c11 - 6.7.9 : paragraph 14) says:

An array of character type may be initialized by a character string literal or UTF−8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.

So, does not specify the bound of a character array in the array initialize.

char a[] = "1234";
msc
  • 33,420
  • 29
  • 119
  • 214
3

You need one more place at the end of the array to store the \0. Declare the arrays with length 5.

You can access the nth element of an array if the array has n elements. Here the size of the arrays are 4 bytes and you are trying to get the 5th byte (as array indices in C start from 0) when you do something like if(a[4] == '\0').

babon
  • 3,615
  • 2
  • 20
  • 20
0

Execute the above code without specifying the array size, in that case all the 3 if statements will be executed, here as we have specified the array size and we know that the array of string will occupy 1 more char for NULL TERMINATION, but here we didn't give chance to the array to behave that way, therefore the compiler behaves randomly.