我正在阅读常见的C陷阱,并在some famous Uni website上发表了这篇文章。 (这是Google上出现的第二个链接)。
该页面上的最后一个示例是
// Memory allocation on the stack
void b(char **p) {
char * str="print this string";
*p = str;
}
int main(void) {
char * s;
b(&s);
s[0]='j'; //crash, since the memory for str is allocated on the stack,
//and the call to b has already returned, the memory pointed to by str
//is no longer valid.
return 0;
}
评论中的解释让我开始思考,那不是字符串文字的记忆不是一成不变的吗?
那不是实际错误,是不是您不应该修改字符串文字,因为它是未定义的行为?还是那里的评论是正确的,而我对该示例的理解是错误的?
进一步搜索后,我看到了一个问题:referencing a char that went out of scope,从这个问题中我了解到,以下是有效的代码。
#include <malloc.h>
char* a = NULL;
{
char* b = "stackoverflow";
a = b;
}
int main() {
puts(a);
}
此question也同意另一个stackoverflow问题和我的想法,但反对该网站代码中的注释。
要对其进行测试,我尝试了以下方法,
#include <stdio.h>
#include <malloc.h>
void b(char **p)
{
char * str = "print this string";
*p = str;
}
int main(void)
{
char * s;
b(&s);
// s[0]='j'; //crash, since the memory for str is allocated on the stack,
//and the call to b has already returned, the memory pointed to by str is no longer valid.
printf("%s \n", s);
return 0;
}
它不会产生分段错误。
答案 0 :(得分:3)
标准说(强调是我的):
6.4.5字符串文字
[...]然后使用多字节字符序列初始化静态存储持续时间数组,长度足以容纳该序列。 [...]
[...] 如果程序尝试执行以下操作: 修改这样的数组,其行为是不确定的。 [...]
答案 1 :(得分:2)
否,您误解了崩溃的原因。字符串文字具有静态持续时间,这意味着它们在程序的生存期内一直存在。由于您的指针指向文字,因此您可以随时使用它。
崩溃的原因是字符串文字是只读的。实际上,Manifest-Version: 1.0
Logging-Profile: myAppLogProfile
是C ++中的错误,应为char* x = ""
。从语言的角度来看,它们是只读的,任何对其进行修改的尝试都将导致未定义的行为。
实际上,它们通常放在只读段中,因此任何修改尝试都会触发 GPF -常规保护错误。通常对GPF的响应是程序终止-这就是您在应用程序中看到的。
答案 2 :(得分:1)
字符串文字通常放在Product
文件的rodata
部分(只读)中,在Linux \ Windows \ Mac-OS下,它们将最终位于一个内存区域中,该内存区域将生成写入时出错(加载时操作系统配置为使用MMU或MPU)