繁体   English   中英

c程序中的分段错误

[英]segmentation fault in c program

只是为了测试我创建了以下代码:

#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;
}

这也导致分段错误在此先感谢

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;
}

也会调用未定义的行为,因为您正在尝试释放尚未使用malloc分配的内存部分(使用free

因为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泄漏),这不是允许修改。

您需要区分对指针的更改以及指针指向的更改

"Hello world"是一个字符串文字 它由存储器区域中的一块字节表示, 可以不被修改 char *p指向那个字节块。 *(p+1) = 'l'表示用指向的*(p+1) = 'l'覆盖指向的下一个字节。 指向的字节后面的下一个字节是可能不被修改的块的一部分。 试图覆盖某些东西是试图修改它。 试图修改不允许修改的内容非常糟糕。

为了具有在存储器中的文本可以被修改的副本,把它放到一个数组,例如char p[] = "Hello world"; (请注意,声明数组这样使得它究竟大到足以容纳字符串,因此,你可能不会延长它,因为没有更多的空间。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM