简体   繁体   中英

Array initialization

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?

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 .

In the case of char foo [] = { 'a', 'd' }; you're declaring an array of characters which has two elements, ie 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.

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.

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 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM