获取分割故障 [英] Getting Segmentation Fault

查看:177
本文介绍了获取分割故障的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到了有关的获取分段错误在C程序中的许多问题在这里SO,我认为这将是巨大的,有那些参考这里,有一些案件正在引起分段错误问题。我的回答是下面贴。


  

写在一些答案中,
  行为是未定义的所有情况下,
  尽管很多人满足他们作为
  分段故障,所以这个问题是什么原因导致这种
  症状。


在以下的情况下,我得到段错误,当我运行该程序,你能确定为什么?

1)

 的char *海峡=富;
海峡[0] ='B'; //<<段错误HRE

2)

 字符海峡[] =富;
字符* =中newstr的malloc(strlen的(STR));
的strcpy(中newstr,STR);
免费(中newstr); //<<段错误这里

3)

 的char *海峡=的malloc(4 * sizeof的(炭));
海峡=富;
免费(STR); //<<段错误这里

4)

 的char *海峡=的malloc(4 * sizeof的(炭));
的strcpy(STR,富);
免费(STR);
如果(STR!= NULL)
    免费(STR); //<<段错误这里

5)

 的char *海峡=的东西,然后富;
的printf(%S,海峡[19]); //<<段错误这里

6)

  typedef结构{
    字符*海峡;
} ST;
...
ST * S;
S =的malloc(sizeof的(ST));
S-GT&; STR =的malloc(5);
免费(S);
免费(S-GT&; STR); //<<段错误这里


解决方案

案例1:

的char *海峡=富; 分配文本段一个字符串,它是只读的地址,并在第二行做,你可以不写它:海峡[0] ='b';
如果要修改的文本,使用字符海峡[] =富; 这将创建一个字符的堆栈的数组并分配它的指针为str。

案例2:

的strlen 返回字符串而不'\\ 0' chracter底,所以的strlen(富)= 3 ,而的strcpy 将字符串包括'\\ 0'字符,因此它复制多个字节比你分配。

案例3:

由于情况1,海峡=富; 分配富的地址 STR ,这意味着你失去了分配内存的地址,而 STR 现在包含一个指向文本段,你不能免费因为它不是在堆中,它的只读存储器中。

案例4:

免费函数不分配 NULL 来作为参数收到的指针(因为它没有解决它,它不能做到这一点)。而你试图调用免费上已经是一个缓冲免费 D。

情况5:

海峡[19] 字符,而不是一个字符指针,而%S预计字符串,这意味着的char * 。被视为是在许多平台上的地址,char是非法地址。 的printf()不检查参数接收。

案例6:

STR 在取值免费 S-&GT的使用> d为错误的。正确的用法将是第一个电话免费(S-> STR); ,然后调用免费(收费); 。前免费释放内部分配的内存ING及其容器。

I saw many questions about getting segmentation fault in C program here in SO, and I thought it would be great to have a reference to those here, a question with some cases that are causing segmentation fault. My answer is posted below.

As written in some answers, the behavior is undefined for all cases, though many people meet them as segmentation fault, so this question is about what causes this "symptom".

In the cases below I get segmentation fault when I run the program, could you determine why?

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

解决方案

Case 1:
char *str = "foo"; assign the address of a string in the text segment which is read only, and you can't write to it as done in the second line: str[0] = 'b';. If you want to modify the text, use char str[] = "foo"; which will create an array of chars on the stack and assign its pointer to str.

case 2:
strlen returns the length of the string without the '\0' chracter at the end, so strlen("foo") = 3, while strcpy copies the string including the '\0' character, so it copies more bytes than you allocated.

case 3:
As in case 1, str = "foo"; assigning the address of "foo" to str, this means that you lose the address of the allocated memory and str now contains a pointer to the text segment which you can't free because it's not on the heap, and its a read-only memory.

case 4:
The free function doesn't assign NULL to the pointer received as parameter (since it doesn't have it address, it can't do that). And you are trying to call free on a buffer that was already freed.

case 5:
str[19] is char, not a char pointer, and "%s" expects string, meaning char *. Treated as as an address on many platform, this char is illegal address. printf() doesn't check the arguments received.

case 6:
The usage of s->str after s is freed is wrong. A correct usage will be to first call free(s->str); and then call free(s);. Free the internal allocated memory before freeing its container.

这篇关于获取分割故障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆