仅用于测试我创建了以下代码:
#include<stdio.h>
int main(){
char *p = "Hello world";
*(p+1) = 'l';
printf("%s", p);
return 0;
}
但是当我在ubuntu 10.04下运行我的“gcc”编译器时,我得到了:
Segmentation fault
所以任何人都可以解释为什么会这样。
#include<stdio.h>
#include<stdlib.h>
int main(){
char *p = malloc(sizeof(char)*100);
p = "Hello world";
*(p+1) = 'l';
printf("%s", p);
free(p);
return 0;
}
这也会导致分段错误 在此先感谢
答案 0 :(得分:5)
char *p = "Hello world";
*(p+1) = 'l';
修改字符串文字的内容(即代码中的“Hello World”)是未定义的行为。
ISO C99(第6.4.5 / 6节)
如果这些数组的元素具有适当的值,则这些数组是否不同是不明确的。 如果程序试图修改此类数组,则行为未定义。
尝试使用字符数组。
char p[] = "Hello World";
p[1] = 'l';
编辑
您修改后的代码
#include<stdio.h>
#include<stdlib.h>
int main()
{
char *p = malloc(sizeof(char)*100);
p = "Hello world"; // p now points to the string literal, access to the dynamically allocated memory is lost.
*(p+1) = 'l'; // UB as said before edits
printf("%s", p);
free(p); //disaster
return 0;
}
也会调用未定义的行为,因为您尝试释放未使用free
分配的内存部分(使用malloc
)
答案 1 :(得分:2)
因为char *p = "Hello world"
几乎肯定会给你一个指向只读内存的指针,这意味着尝试用*(p+1) = 'l'
来改变它是一个明确的禁忌(即使内存未被读取) - 只是,行为仍未定义。)
C99引用字符串文字的相关部分位于6.4.5 para 6
:
如果这些数组的元素具有不同的数据,则未指定 适当的价值观如果程序试图修改这样的数组,则行为是 未定义。
你仍然因为以下内容而导致分段错误的原因:
char *p = malloc (100); // sizeof(char) is ALWAYS 1
p = "Hello"; // better would be: strcpy (p, "Hello")
*p = 'a';
是因为,即使您正在分配允许修改的内存,第二个语句也会将指针更改为指向字符串文字(当您失去访问权限时会导致mmory泄漏) <分配内存),不允许修改。
您需要将对指针的更改与指针指向的更改区分开来。
答案 2 :(得分:1)
"Hello world"
是一个字符串文字。它由内存区域中的一块字节表示,可能未被修改。 char *p
指向那个字节块。 *(p+1) = 'l'
表示用尖头的'l'覆盖下一个字节。指向的字节后面的下一个字节是可能不被修改的块的一部分。试图覆盖某些东西是试图修改它。试图修改不允许修改的内容非常糟糕。
为了在内存中复制文本可能进行修改,请将其放入数组中,例如: char p[] = "Hello world";
。 (请注意,以这种方式声明数组会使完全大到足以容纳字符串,因此可能不会延长,因为没有更多空间。)