简体   繁体   中英

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??

在此处输入图像描述

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.

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.

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 .

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.

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