获取分段错误

时间:2011-04-29 15:29:03

标签: c segmentation-fault access-violation

我在SO中看到了很多关于得到分段错误的问题,我认为在这里引用这些问题会很棒,这个问题会引起一些导致分段错误的问题。我的答案发布在下面。

  

正如在一些答案中写的那样   行为未定义所有情况,   虽然很多人都认为他们是   细分错误,所以这个问题是关于是什么原因造成的   “症状”。

在下面的例子中,当我运行程序时出现分段错误,你能确定原因吗?

1)

char *str = "foo";
str[0] = 'b';   // << Segfault hre

2)

char str[] = "foo";
char *newStr = malloc(strlen(str));
strcpy(newStr, str);
free(newStr);   // << Segfault here

3)

char *str = malloc(4 * sizeof(char));
str = "foo";
free(str);      // << Segfault here

4)

char *str = malloc(4 * sizeof(char));
strcpy(str, "foo");
free(str);
if (str != NULL)
    free(str);      // << Segfault here

5)

char *str = "something and then foo";
printf("%s", str[19]);    // << Segfault here

6)

typedef struct {
    char *str;
}st;
...
st *s;
s = malloc(sizeof(st));
s->str = malloc(5);
free(s);
free(s->str);    // << Segfault here

5 个答案:

答案 0 :(得分:9)

您的所有示例都会导致未定义的行为,这可能会导致崩溃(或者可能根本不会造成任何伤害)。

  1. 您不能更改字符串文字。 (参见例如here

  2. 您忘记为终止空字节分配存储空间,执行malloc(strlen(str) + 1);

  3. 你在没有从malloc(或类似函数)获得的指针上调用free()。当你使str指针指向一个字符串文字时,你已经丢失了指向malloc和内存泄漏的内存的指针。

  4. 你在同一个指针上调用free()两次,这是未定义的行为。

  5. printf格式字符串中的%s告诉printf该参数是一个字符串(指向一系列nul终止字符的char *)您传递的是char,而不是字符串。如果要打印字符串的后缀,请使用printf("%s", &str[19]);

  6. 您传入了一个指向free()的无效指针,您已经免费s,以后执行s->str时无法取消引用它。撤消释放的顺序:free(s->str); free(s);

答案 1 :(得分:4)

案例1:
char *str = "foo";分配文本段中字符串的地址,该字符串是只读的,您不能像在第二行中那样写入它:str[0] = 'b';。 如果要修改文本,请使用char str[] = "foo";,它将在堆栈上创建一个字符数组,并将其指针指定给str。

案例2:
strlen返回结束时没有'\0'字符的字符串的长度,因此strlen("foo") = 3,而strcpy复制包含'\0'字符的字符串,所以它复制比您分配的字节多。

案例3:
与情况1一样,str = "foo";将地址“foo”分配给str,这意味着您丢失了已分配内存的地址,str现在包含指向文本段的指针你不能free因为它不在堆上,而且它是一个只读存储器。

案例4:
free函数不会将NULL分配给作为参数接收的指针(因为它没有地址,所以不能这样做)。您正试图在已经free d。

的缓冲区上调用free

案例5:
str[19]char,而不是char指针,"%s"需要字符串,意思是char *。在许多平台上被视为地址,这个字符是非法地址。 printf()不会检查收到的参数。

案例6:
s->str s之后使用free是错误的。正确的用法是先拨打free(s->str);,然后拨打free(s);。在free容器之前释放内部分配的内存。

答案 2 :(得分:3)

  1. 未定义的行为:尝试更改字符串文字
  2. 未定义的行为:写过数组末尾
  3. 未定义的行为:向free()传递未通过malloc()获取的指针
  4. 未定义的行为:传递给free()无效指针
  5. 未定义的行为printf()格式说明符与实际参数类型之间的不兼容性
  6. 未定义的行为:传递给free()无效指针
  7. 未定义的行为可以通过“分段错误”表现出来,但这绝不是必需的结果。任何事情都可能发生:)

答案 3 :(得分:1)

  1. 您尚未分配任何内存。 * str只是一个指针。
  2. 段错误的原因在第2行,你需要malloc strlen()+ 1,因为字符串分隔符'\ 0'

答案 4 :(得分:1)

3:“foo”是一个常量字符串,不是动态分配的。

旁注:这也是内存泄漏。