-1

What's the difference between

char string[3] = "ABC";
char* pString = string;
printf("%s", pString);

and

char* pString = "ABC";
printf("%s", pString);

First code prints ABC with 2 random ascii words at the end while second one only prints ABC.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
howdoyoudo
  • 55
  • 3

3 Answers3

2

The first example creates an array with three elements. It's equivalent to

char string[3] = { 'A', 'B', 'C' };

The second example uses the string literal "ABC" which is an array of four characters, and then make the pointer pString point to the first character. It's equivalent to

char compiler_internal_string[4] = { 'A', 'B', 'C', '\0' };
char *pString = &compiler_internal_string[0];

Note how the two arrays are different: Your doesn't have the terminating null-character that all string-related functions look for to know when the string ends.

Since your array is missing the terminator, all string function will go out of bounds of the array, and that leads to undefined behavior.

Unless you want to make an array larger than the string it contains, for example to be able to append to it, then the simple solution is to just not provide the size:

char string[] = "ABC";  // Will create an array of four characters,
                        // and include the terminator

On another note, literal strings are not modifiable, they are in effect read-only. Therefore it's recommended to use const char * pointers to point to string literals, to make the chances of accidental modifications smaller.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

In your first snippet the variable string is a mutable character array. It is not actually a string as it's missing the terminating '\0'. As printf("%s", ...) expects a string your program will have undefined behavior. Either use a bigger array, most often by not specifying a size, so the compiler can derive the right size which in this case is 4:

char string[] = "ABC";

or specify a maximum field with when printing the character array:

printf("%.3s", string);

In the 2nd snippet pString is a pointer to non-mutable string literal, and it will print out the expected string:

ABC
Allan Wind
  • 23,068
  • 5
  • 28
  • 38
1

In this declaration

char string[3] = "ABC";

the string literal "ABC" used as an initializer has the type char[4] (in C++ it has the type const char[4]) that is it is represented in memory like

{ 'A', 'B', 'C', '\0' }

However the initialized array has only 3 elements. So the terminating zero character '\0' of the string literal is not stored in the array. As a result the array does not contain a string and this call of printf

printf("%s", pString);

invokes undefined behavior because the conversion specifier %s expects a pointer to a string: a sequence of characters terminated by the zero character '\0'.

Instead you could write for example

printf("%.3s", pString);

or

printf("%.*s", 3, pString);

specifying in the call of printf that you want to output exactly 3 `characters.

Such a declaration of a character array is valid in C but is not valid in C++.

You could rewrite the declaration like for example

char string[] = "ABC";

In this case all 4 characters of the string literal were used as initializers and the array would contain a string.

In the second code snippet there is outputted a string because the pointer pString points to a string

char* pString = "ABC";
printf("%s", pString);

So there is no problem with the call of printf.

halfer
  • 19,824
  • 17
  • 99
  • 186
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335