too much php
too much php

Reputation: 91068

C string initializer doesn't include terminator?

I am a little confused by the following C code snippets:

printf("Peter string is %d bytes\n", sizeof("Peter")); // Peter string is 6 bytes

This tells me that when C compiles a string in double quotes, it will automatically add an extra byte for the null terminator.

printf("Hello '%s'\n", "Peter");

The printf function knows when to stop reading the string "Peter" because it reaches the null terminator, so ...

char myString[2][9] = {"123456789", "123456789" };
printf("myString: %s\n", myString[0]);

Here, printf prints all 18 characters because there's no null terminators (and they wouldn't fit without taking out the 9's). Does C not add the null terminator in a variable definition?

Upvotes: 6

Views: 4882

Answers (7)

Eddie
Eddie

Reputation: 54421

If you tell C that an array is a given size, C cannot make the array any larger. It would be disobeying you if it did so! Remember that not every char array contains a null terminated string. Sometimes the array (as used) is truly an array of (individual) char. The compiler doesn't know what you are doing and cannot read your mind.

This is why C allows you to initialize a char array where the null terminator won't fit but everything else will. Try your example with a string one byte longer and the compiler will complain.

Note that your example will compile but will not do what you expect, as the contents are not (null terminated) strings. With GCC, running your example, I see the string I should, followed by garbage.

Upvotes: 3

Alex B
Alex B

Reputation: 84922

C allows unterminated strings, C++ does not.

C allows character arrays to be initialized with string constants. It also allows a string constant initializer to contain exactly one more character than the array it initializes, i.e., the implicit terminating null character of the string may be ignored. For example:

char  name1[] =  "Harry";   // Array of 6 char

char  name2[6] = "Harry";   // Array of 6 char

char  name3[] =  { 'H', 'a', 'r', 'r', 'y', '\0' };
                            // Same as 'name1' initialization

char  name4[5] = "Harry";   // Array of 5 char, no null char 

C++ also allows character arrays to be initialized with string constants, but always includes the terminating null character in the initialization. Thus the last initializer (name4) in the example above is invalid in C++.

Upvotes: 2

Sébastien RoccaSerra
Sébastien RoccaSerra

Reputation: 17211

Alterenatively, you can use:

char* myString[2] = {"123456789", "123456789" };

Like this, the initializer computes the right size for your null terminated strings.

Upvotes: 2

Chris Lutz
Chris Lutz

Reputation: 274

The '\0' byte isn't it's problem. Most of the time, if you have this:

char code[9] = "123456789";

The next byte will be off the edge of the variable, but will be unused memory, and will most likely be 0 (unless you malloc() and don't set the values before using them). So most of the time it works, even if it's bad for you.

If you're using gcc, you might also want to use the -Wall flag, or one of the other (million) warning flags. This might help (not sure).

Upvotes: 0

too much php
too much php

Reputation: 91068

Is there a reason why the compiler doesn't warn that there isn't enough room for the 0 byte? I get a warning if I try to add another '9' that won't fit, but it doesn't seem to care about dropping the 0 byte?

Upvotes: 0

Sean Bright
Sean Bright

Reputation: 120704

Sure it does, you just aren't leaving enough room for the '\0' byte. Making it:

char string[2][10] = { "123456789", "123456789" };

Will work as you expect (will just print 9 characters).

Upvotes: 6

Chris Lutz
Chris Lutz

Reputation: 274

Your string is [2][9]. Those [9] are ['1', '2', etc... '8', '9']. Because you only gave it room for 9 chars in the first array dimension, and because you used all 9, it has no room to place a '\0' character. redefine your char array:

char string[2][10] = {"123456789", "123456789"};

And it should work.

Upvotes: 25

Related Questions