可能重复:
Difference between char *str=“STRING” and char str[] = “STRING”?
我写了以下代码:
int main()
{
char *str = "hello";
str[0] = 'H';
printf("%s\n", str);
}
这给我一个分段错误,我不明白为什么。
str
pointer to char
不是const char
。即使是这种情况,也不应该像下面的程序那样给出编译错误:
int main()
{
const char *str = "hello";
str[0] = 'H';
printf("%s\n", str);
}
它出错:assignment of read-only location *str
。
修改
如果我的代码将指针放在只读位置,我不应该得到编译错误吗?
答案 0 :(得分:5)
指定一个指向常量字符串的指针(它作为文本的一部分,因此不是可写内存)。
修复char str[] = "hello";
这将在您的堆栈上创建常量字符串的r / w副本。
您所做的是完全有效的指针赋值。编译器不知道的是,在标准系统中,常量字符串放在只读存储器中。在嵌入式(或其他奇怪的)系统上,这可能是不同的。
根据您的系统,您可以使用mprotect
并将指针目标上的VM标志更改为可写。因此,编译器允许使用此代码,但您的操作系统不会。
答案 1 :(得分:2)
当您使用文字字符串初始化char *
时,您不应该尝试修改它的内容:该变量指向不属于您的内存。
你可以使用:
char str[] = "hello";
str[0] = 'H';
使用此代码,您已声明一个数组,该数组使用文字字符串内容的副本进行初始化,现在您可以修改该数组。
答案 2 :(得分:0)
您的代码在运行时具有未定义的行为。您正在尝试写入文字字符串,这是不允许的。此类写入可能会触发错误或具有未定义的行为。您的特定C编译器有str
指向只读内存,并且尝试写入该内存会导致分段错误。即使它不是const
,仍然不允许写入。
答案 3 :(得分:0)
char *str = "hello";
如上所述声明str
时,无法保证将存储哪部分内存。 str可能是只读的,具体取决于实现。所以试图改变它会导致分段错误。
为了避免细分faullt,请将str
声明为字符数组。
答案 4 :(得分:0)
char *str = "hello";
这里的字符串hello是一个文字。 字符串文字始终存储在只读存储器中。 当您尝试更改只读内存中的值时,这就是您遇到分段错误的原因。
答案 5 :(得分:0)
将str声明为char *为指针保留内存,但不为字符串保留内存。 编译器可以将内存放入" hello"他喜欢的地方。 你不能保证str [i]是可写的,这就是为什么在某些编译器中会导致seg错误的原因。
如果你想确保字符串在可写内存中,那么你必须使用alloc()分配内存,或者你可以使用
char str[] = "hello";