c程序中的分段错误

时间:2010-12-11 12:32:24

标签: c gcc segmentation-fault

仅用于测试我创建了以下代码:

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

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

3 个答案:

答案 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";。 (请注意,以这种方式声明数组会使完全大到足以容纳字符串,因此可能不会延长,因为没有更多空间。)