Daros911
Daros911

Reputation: 435

Defining a string literal

What's the difference between this two literal string definitions?:

const char *message1 = "message1";
const char message2[] = "message2";

If both of them are null-terminated it's so strange - when i pass the first one to some text printing function I get an "memory could not be written" error but when pass the second everything is OK!?

enter image description here

The function of question is some 3-rd party function from Fallout 2 game mod source called sfall. The function as far as i know calls the native Fallout 2 engine defined function which the sfall code calls by it's own wrapper.

Upvotes: 1

Views: 120

Answers (3)

Drew Dormann
Drew Dormann

Reputation: 63745

What's the difference between this two literal string definitions?

message1 is a pointer to a string literal.

message2 is an array copy of a string literal.

Consider a hypothetical hostile printing function

void hostile_print( const char* msg )
{
    const_cast<char*>(msg)[0] = 0;
}

In the code below, the address of this string literal could be located in memory that the OS has marked as read-only. That's not uncommon for string literals.

Regardless, hostile_print commits Undefined Behavior and the OS gives you that angry dialog box. Because Undefined Behavior can look like that.

const char *message1 = "message1";
hostile_print(message1);

In the code below, the address of the array could be located in memory that the OS has marked as writable. Perhaps the stack. That's not uncommon for local arrays.

Regardless, hostile_print commits Undefined Behavior and the program proceeds as expected. Because Undefined Behavior can look like that.

const char message2[] = "message2";
hostile_print(message2);

In either case, the function is writing to memory that it shouldn't.

Upvotes: 1

Dundo
Dundo

Reputation: 764

In the first case the string literal decays to pointer.

In the second case the string literal gets stored to an array of char that the compiler will automatically size to fit the literal complete with the null terminator.

With the second you are retaining more information in your variable. So for example you can call std::size on the second but not on the first.

Calling a printing function that takes const char* should be the same with both cases. Since in the second case the const char[] would decay to pointer at the moment of the function call.

Upvotes: 2

Mushfiqur Rahman
Mushfiqur Rahman

Reputation: 74

const char message2[] = "message2";

"message2" will be placed in read-only memory. Then its characters are copied to the allocated memory of the message2[] array.

const char *message1 = "message1";

"message1" will be placed in read-only memory. message1 will simply be a pointer to that memory.

In both examples, values are constant.

Upvotes: 2

Related Questions