1

I have two types of array initialisation that will be used in string constructor

int main() {
    //char foo [] = { 'a', 'd' }; 
    char foo[] = "ad";

    std::string s = foo;

    cout<<s;

    int i;
    cin >> i;
}

Why in char foo [] = { 'a', 'd' }; case i have output:

ad╠╠╠╠╠╠R8$1↑■╬

And when array is initialized like char foo [] = "ad"; I have normal output -ad- that was expected in first case.

What is difference in these two array initialization and why I have garbage in output in first one?

4
  • char foo [] = { 'a', 'd' }; does not have a terminating null character, but char foo [] = "ad"; does. Commented Oct 5, 2015 at 13:07
  • omg people stop writing answers in comments ffs Commented Oct 5, 2015 at 13:10
  • @LightnessRacesinOrbit Those aren't really answers. They are kind of half-answers (a bit like the posted answers) Commented Oct 5, 2015 at 13:12
  • @juanchopanza: They totally don't belong in the comments section. The whole point of SO's existence is to do vote-ranked Q&A properly, not a willy-nilly assortment of half-answers, chatty tips and hints in a chronological list like a message board. I don't understand why everybody seems so intent on sabotaging this highly successful model all of a sudden. Unfortunately I also seem to be the only person who cares. :( Commented Oct 5, 2015 at 13:13

4 Answers 4

3

You need the string to be null terminated

char foo [] = { 'a', 'd', '\0' };

String literals are already null terminated.

§ 2.14.5 String Literals

8 Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char, where n is the size of the string as defined below, and has static storage duration

14 After any necessary concatenation, in translation phase 7, '\0' is appended to every string literal so that programs that scan a string can find its end.

Sign up to request clarification or add additional context in comments.

6 Comments

But foo isn't a const char*.
@CoryKramer: No, the literal is not a const char*.
No, a char[] isn't a thing in this context. There's more stuff going on, that you aren't really explaining.
@CoryKramer a string literal has the type of array of n const char (C++14 2.13.5(8))
I have updated the description of string literals with snippets from the C++ standard, hopefully that more thoroughly explains the behavior.
|
1

In the case of char foo [] = { 'a', 'd' }; you're declaring an array of characters which has two elements, i.e. not a null terminated string. So when you try to print it as a string, the << operator keeps reading whatever characters happen to follow until if finds a null byte. This is undefined behavior.

In the case of char foo [] = "ad"; you're initializing a character array with a string constant. This constant has 3 characters, namely "a", "d", and a null byte, so the array is 3 characters long. So when you print this, it prints properly.

1 Comment

Almost, but a bit misleading. I don't think your second paragraph is quite right.
1
char foo[] = "ad";

Actually creates a char array of

char foo[] = { 'a', 'd', '\0' };

The '\0' is important as it is used to signal the end of a char array. When you create the string s the contents of foo are read until the '\0' is reached. When you output s you get ad . When you do

char foo [] = { 'a', 'd' };

there is no '\0' so when you create the string s the constructor will keep going until it reaches a '\0'. This is undefined behavior as we are using memory we have not allocated.

3 Comments

It is s, not foo that is being outputed.
@juanchopanza thanks for pointing that out. fixed it to talk about the string creation.
I think the part that is missing is that there is no string constructor that can infer the length of an array, but there is one that takes const char*, so overload resolution picks that one after array decay.
0

When you write

std::string = foo; // copy ctor --  for std::string will be called

Which expects a null terminated ( C style) string. But in case of following you don't have a null character to terminate the C style string.

char foo [] = { 'a', 'd' }; // Incorrect
char foo[] =  { 'a', 'd' ,'\0'}; //Correct

It is fine in case of following as compiler will generate a null terminate C string for you.

char foo[] = "ad";

Also one thing to note that "ad" is a string literal, and { 'a', 'd' ,'\0'} is an array initializer. Following is notable here

char[] foo = "ad";
foo[1] = 'M'; // Undefined behavior 

char[] foo = { 'a', 'd' ,'\0'};
foo[1] = 'M'; // Is OK 

1 Comment

"as compiler will generate a null terminate C string for you" Right, but explain why. Explain what difference in the code leads to this happening.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.