如何解决重用悬空指针或空指针时出错分段错误
#include<stdlib.h>
#include<string.h>
int main ( void )
{
char *title=NULL;
title = (char *) malloc(15);
strcpy(title,"C Programming");
printf("String = %c",*title);
free(title);
// title=NULL; //or title = 0;
strcpy(title,"C++");
printf(" %s",title);
return 0;
}
当我取消注释“title=NULL”行时,程序会因分段错误而崩溃;有人可以解释这种行为吗
否则打印“String = C C++”
解决方法
如果您的代码取消引用悬空指针或空指针,则行为为 undefined - 任何事情都可能发生。这两种可能的行为(“它按预期工作”和“它崩溃”)实际上是未定义行为的最常见表现。
有时,您可以将未定义的行为合理化 - 就像在这种情况下一样。但你不能总是指望它是可以理解的。
- 如果您的代码尝试将内容写入空地址,则会崩溃,因为操作系统可以检测到这一点。这非常简单(空指针指向一个不可读和不可写的内存页)并且很有用(一个好的调试器会直接停在有问题的代码行)。
- 如果您的代码尝试重用悬空指针,它指向的地址通常仍然是可写的 -
free
不会告诉操作系统它现在处于悬空状态。free
只会编辑一些簿记数据结构,因此释放的地址可用于未来分配。访问悬空指针时不容易导致崩溃,因为操作系统只能在页面粒度上管理内存访问,这可以是 4 KiB 或类似的东西。
90% 的问题是 red herring。整个问题可以在一行中重述:
当我这样做时: 标题=空; strcpy(title,"C++"); 我的程序崩溃了。为什么?
上面的代码尝试将字节写入空指针引用的内存地址。根据定义,这是未定义的行为。未定义的行为意味着任何事情都可能发生,例如一碗矮牵牛和抹香鲸可能会从天而降,但在那里的绝大多数执行环境中,当然在您的执行环境中,空指针引用的内存地址不是可写,因此这将始终导致您遇到的确切行为:分段错误。
此外,为了解决问题的其余部分,当将指针设置为 NULL 的行被注释掉时,您正在写入已释放的内存位置。由于它已被释放,因此永远不应再次访问它,并且再次访问它是未定义的行为,只有在这种情况下,才没有检测误用的机制,因此它恰好是巧合。尝试在不同的环境中运行相同的程序,就会有盆栽矮牵牛和抹香鲸从天而降。
,这是未定义的行为。您通过执行 free(title)
告诉操作系统您的程序不再需要内存,但这并不意味着内存会立即从您的进程中获取。相反,title
仍然保留(现在已释放且未考虑)内存的地址,随后的 strcpy()
(取决于操作系统及其内存使用策略)可能能够写入该内存和 printf()
将获得地址(再次释放和下落不明)并打印字符,直到它到达第一个 \0
之前放在那里的 strcpy()
。
当您在释放它后将 title
正确设置为 NULL
时,期望指向已分配内存的指针的其他函数(此处为 strcpy()
)将获得无效输入并失败(出现分段错误)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。