MBy*_*ByD 15 c segmentation-fault access-violation
我在SO中看到了很多关于在C程序中获取分段错误的问题,我认为在这里引用这些是很好的,这是一些导致分段错误的问题.我的答案发布在下面.
正如在一些答案中所写,对于所有情况,行为都是未定义的,尽管许多人将它们视为 分段错误,因此这个问题是关于导致这种"症状"的原因.
在下面的例子中,当我运行程序时出现分段错误,你能确定原因吗?
1)
char *str = "foo";
str[0] = 'b'; // << Segfault hre
Run Code Online (Sandbox Code Playgroud)
2)
char str[] = "foo";
char *newStr = malloc(strlen(str));
strcpy(newStr, str);
free(newStr); // << Segfault here
Run Code Online (Sandbox Code Playgroud)
3)
char *str = malloc(4 * sizeof(char));
str = "foo";
free(str); // << Segfault here
Run Code Online (Sandbox Code Playgroud)
4)
char *str = malloc(4 * sizeof(char));
strcpy(str, "foo");
free(str);
if (str != NULL)
free(str); // << Segfault here
Run Code Online (Sandbox Code Playgroud)
5)
char *str = "something and then foo";
printf("%s", str[19]); // << Segfault here
Run Code Online (Sandbox Code Playgroud)
6)
typedef struct {
char *str;
}st;
...
st *s;
s = malloc(sizeof(st));
s->str = malloc(5);
free(s);
free(s->str); // << Segfault here
Run Code Online (Sandbox Code Playgroud)
您的所有示例都会导致未定义的行为,这可能会导致崩溃(或者可能根本不会造成任何伤害).
您不能更改字符串文字.(见例如这里)
你忘了为终止的nul字节分配存储空间了 malloc(strlen(str) + 1);
你在一个你没有从malloc(或类似函数)获得的指针上调用free().当你使str
指针指向一个字符串文字时,你已经丢失了指向分配了malloc和内存泄漏的内存的指针.
你在同一个指针上调用free()两次,这是未定义的行为.
printf格式字符串中的%s告诉printf该参数是一个字符串(指向nul终止字符序列的char*)您传递的是char,而不是字符串.如果要打印字符串的后缀使用printf("%s", &str[19]);
你传递了一个指向free()的无效指针,你已经自由了,你以后就不能取消s
引用它了s->str
.反转释放的顺序:free(s->str); free(s);
情况1:
char *str = "foo";
在只读的文本段中分配一个字符串的地址,您不能像第二行那样写入它:str[0] = 'b';
。如果要修改文本,请使用char str[] = "foo";
which 将在堆栈上创建一个字符数组并将其指针分配给 str。
情况 2:
strlen
返回末尾没有字符的字符串的长度'\0'
,因此strlen("foo") = 3
,while 会strcpy
复制包含'\0'
字符的字符串,因此它复制的字节数比您分配的字节数多。
情况 3:
与情况 1 一样,str = "foo";
将“foo”的地址分配给str
,这意味着您丢失了已分配内存的地址,str
现在包含一个指向文本段的指针,free
因为它不在堆上,因此您不能这样做,并且它是一个只读存储器。
情况 4:
该free
函数不会分配NULL
给作为参数接收的指针(因为它没有地址,所以不能这样做)。而你正试图调用free
一个已经是free
d的缓冲区。
情况 5:
str[19]
is char
,不是字符指针,并且"%s"
需要字符串,意思是char *
. 在许多平台上被视为地址,这个字符是非法地址。printf()
不检查收到的参数。
case 6: after is d
的用法是错误的。正确的用法是先调用然后调用。在容器之前释放内部分配的内存。s->str
s
free
free(s->str);
free(s);
free