C程序中的分段错误
只是为了测试我创建了以下代码:
#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;
}
这也会导致分段错误 提前致谢
just for testing i had created the following code:
#include<stdio.h>
int main(){
char *p = "Hello world";
*(p+1) = 'l';
printf("%s", p);
return 0;
}
But when i ran this over my "gcc" compiler under ubuntu 10.04 I got:
Segmentation fault
So can anyone explain this why this happened.
#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;
}
this also cause a segmentation fault
Thanks in Advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
修改字符串文字的内容(即代码中的“Hello World”)是未定义行为。
ISO C99(第 6.4.5/6 节)
尝试使用字符数组。
编辑
您修改的代码
也会调用未定义的行为,因为您试图释放尚未使用
mallocfree
) >Modiying the content of a string literal (i.e "Hello World" in your code) is Undefined Behavior.
ISO C99 (Section 6.4.5/6)
Try using array of characters.
EDIT
Your modified code
invokes Undefined Behaviour as well because you are trying to deallocate the section of memory (using
free
) which has not been allocated usingmalloc
因为
char *p = "Hello world"
几乎肯定为您提供了一个指向只读内存的指针,这意味着尝试使用*(p+1) = 'l' 更改它
是明确的禁忌(即使内存不是只读的,行为仍然是未定义的)。C99 引用字符串文字的相关部分位于
6.4.5 para 6
中:您仍然遇到类似以下情况的分段错误的原因
是:即使您分配了允许修改的内存,第二个语句也会更改指针 指向一个字符串文字(当您无法访问已分配的内存时,会导致内存泄漏),并且不允许您对其进行修改。
您需要区分对指针的更改和对指针所指内容的更改。
Because
char *p = "Hello world"
has almost certainly given you a pointer to read-only memory and that means that trying to change it with*(p+1) = 'l'
is a definite no-no (even if the memory isn't read-only, the behaviour is still undefined).The relevant part of C99 referring to string literals is in
6.4.5 para 6
:The reason why you still get a segmentation fault with something like:
is because, even though you're allocating memory which you're allowed to modify, the second statement changes the pointer to point to a string literal (giving you a mmory leak as you lose access to the allocated memory), which you are not allowed to modify.
You need to differentiate changes to the pointer from changes to what the pointer points at.
“Hello world”
是一个字符串文字。它由内存区域中的一个字节块表示,不能修改。char *p
指向该字节块。*(p+1) = 'l'
表示用“l”覆盖指向的字节之后的下一个字节。所指向的字节之后的下一个字节是不可修改的块的一部分。尝试覆盖某些内容就是尝试修改它。试图修改不允许修改的东西是非常糟糕的。为了在内存中获得可以修改的文本副本,请将其放入数组中,例如
char p[] = "Hello world";
。 (请注意,以这种方式声明数组使其恰好足够大以容纳字符串,因此您可能不会延长它,因为没有更多空间。)"Hello world"
is a string literal. It is represented by a chunk of bytes in a region of memory which may not be modified.char *p
points at that chunk of bytes.*(p+1) = 'l'
says to overwrite the next byte after the pointed-at one with an 'l'. The next byte after the pointed-at one is part of the chunk which may not be modified. Attempting to overwrite something is attempting to modify it. Attempting to modify something which is not allowed to be modified is very bad.In order to have a copy of the text in memory which may be modified, put it into an array, e.g.
char p[] = "Hello world";
. (Notice that declaring the array this way makes it exactly big enough to hold the string, and therefore you may not lengthen it, since there is no more room.)