const char* vs const char[]
Asked Answered
N

3

23

As far as I know , a string literal like "Hello"

is considered a char* in C and a const char* in C++ and for both languages the string literals are stored in read-only memory.(please correct me if I am wrong)

#include <stdio.h>

int main(void)
{
    const char* c1;
    const char* c2;

    {
        const char* source1 = "Hello";
        c1 = source1;

        const char source2[] = "Hi"; //isn't "Hi" in the same memory region as "Hello" ?
        c2 = source2;
    }

    printf("c1 = %s\n", c1); // prints Hello
    printf("c2 = %s\n", c2); // prints garbage

    return 0;
}

Why source1 and source2 behave differently ?(compiled with gcc -std=c11 -W -O3)

Newmarket answered 12/3, 2015 at 11:21 Comment(7)
Assigning pointers in this way is incorrect! Use strcpyFeldt
@Feldt I didn't get even any warning while compilingNewmarket
The source2 version temporarily creates a local array on the stack, which has gone out of scope by the time you print c2. If you want to mimic a string literal in a constant ("text") segment then use static instead of automatic storage.Rarity
I just tested it on gcc version 4.8.2 and it prints the following c1 = Hello c2 = Hi used the -std=c11 flag as wellSmalt
In C++ string literals are type const char [] of whatever length. They decay into const char * pointers.Zamora
Accessing the memory area of source1 and source2 after they have gone out of scope invokes undefined behaviour.Nan
@Smalt I'm terrible sorry , I added -O3 and then got the garbage, if could help me with this one , that would be great because now the answers are not exactNewmarket
A
15

In this code snippet

{
 const char* source1 = "Hello";
 c1 = source1;

 const char source2[] = "Hi"; //isn't "Hi" in the same memory region as "Hello" ?
 c2 = source2;
}

source2 is a local character array of the code block that will be destroyed after exiting the block that is after the closing brace.

As for the character literal then it has static storage duration. So a pointer to the string literal will be valid after exiting the code block. The string literal will be alive opposite to the character array.

Take into account that in C the type of string literal "Hello" is char [6]. That is the type of any string literal is a non-const character array. Nevertheless you may not change string literals. Opposite to C in C++ character literals have types of const character arrays.

Allin answered 12/3, 2015 at 11:26 Comment(2)
compiling without the -O3 option I get printed : c1 = Hello c2 = Hi so know I'm confusedNewmarket
@Newmarket The program behaviour is undefined when you try to access an object that is not already alive. Simply in the last case the memory early allocated for the array was not yet overwritten.Allin
S
9
const char* source1 = "Hello";

source1 is just pointer on memory-location, where Hello is defined.

const char source2[] = "Hi";

source2 is local variable of type array of chars and has another address, that string-literal Hi. After first } source2 will be destroyed and c2 will be pointed somewhere, but not on location of source2, so it's just undefined behaviour to dereference c2 after source2 is destroyed.

Skink answered 12/3, 2015 at 11:25 Comment(4)
so in this case "Hi" will be created in the same memory location as "Hello" but the content of "Hi" will be copied to a temp array source2 ? after that I will lose my contents of the source2 array BUT "Hi" will still reside in my read only memory region ?Newmarket
@Newmarket yes, all string-literals are in read only memory region, but it's implementation-defined, that they are stored distinct, or not.Skink
@Newmarket undefined behaviour is undefined.Skink
you can see actual pointer value by usage of %p printf format modifier:In this case first string is really points to the text section 0x400754 but second string points to the stack 0x7fffaf9130c8, along with other local variables.Inbred
O
2

isn't "Hi" in the same memory region as "Hello"?

You are (subtly) mistaken. "Hello" on it's own is an expression that's not of type (const) char *, but of type (const) char[6]. char source2[] = "Hi"; is a statement that defines, declares and initialises a char [3] object. There is no const char * in sight. In a function scope that object has automatic storage duration.

In your usage, source2 ceases to exist at the following }, and makes c2 an invalid pointer. The use of c2 later is undefined.

Oxidation answered 20/12, 2018 at 15:26 Comment(1)
@adabsurdum seems like I was missing a not in that sentenceOxidation

© 2022 - 2024 — McMap. All rights reserved.