当我尝试访问已经释放的地址时,程序将正常运行。 有一些货物可以避免吗? 像一些名为have_alloca(void *p)函数可以返回p是否是一个有效的地址。
我知道valgrind与tool=memcheck可以做到这一点。 但是我想知道是否可以从代码中避免它。
这里是一个简单的例子:
#include <stdlib.h> int main(int argc,char *argv[]) { int *p = malloc(sizeof(int) * 10); free(p); *(p + 1) = 100; return 0; }
为什么我可以访问一个无效的地址? 程序可以编译运行,不会有任何警告。 顺便说一句:Linux。
是否有可能在用户空间分配Linux上的不可caching的内存块?
保留RAM中的数据,同时允许其他进程在Linux C ++中访问它
cachingDMA环境中的一致性问题
如何通过PCIe总线读取正在使用的带宽?
BASH:检查安装在系统上的内存数量是否完整
不,你必须自己照顾这个。
从技术上讲,从语言标准的角度来看,不属于你的内存位置是Undefined Behavior 。
C语言和C ++语言为您提供了灵活的方式来访问变量的地址并使用它们,代价是这些地址包含变量/对象所拥有的有效值。
理由是:
“权力越大,责任越大”
所以你要承担责任。
p就像一个正常的变量
函数free(p)的调用只是释放我们分配的内存,但是p仍然保存地址值 。 除非你自己重置:
p = NULL;
所以请记住以下提示:
每次在使用指针之前,请检查它是否为空指针。
每次释放内存后,都将NULL设置为指针。
释放NULL指针后,将NULL指定给指针。
在访问之前检查不是NULL 。
除了其他的回复之外,你可以考虑使用Boehm的保守的垃圾收集器 ,那么你可以使用GC_malloc而不是malloc而且你不会做任何free事情(即使在绝对确定内存区变得无用和无法访问的时候,明确GC_free它)。
但是C的一点是,你不能使用free数据区。 这样做是不确定的行为 ,任何事情都可能发生。
至于“为什么你有时还会访问一个无效的地址”(在一个free区域内),答案是具体的实现。 实际上,在Linux上,通过mmap(2) (或者有时sbrk(2) )从内核获取内存,然后通过munmap(2)系统调用来完成,而这些调用在某种程度上是昂贵的操作,需要处理多个的页面长度(通常是4K字节)。 所以malloc实现会尽量避免做大量的mmap和munmap系统调用,所以通常通过不同的方式来管理free内存区域,通过组织它们,这样它们可以在不使用任何mmap系统调用的情况下被进一步的malloc重用。 这解释了内存区域仍然存在(即使它在malloc内部簿记中),您可以访问它。 但是这样做会打破malloc的内部不变量,破坏会在后面发生。
顺便说一句,如果地址在地址空间内,则地址是有效的,并且可以通过读取(顺序地)读取/proc/1234/maps文件(在Linux上具有指定文本内容的伪文件)来查询进程1234的地址空间。 从进程内部读取/proc/self/maps 。 尝试使用命令cat /proc/self/maps来显示运行该cat命令的进程的地址空间,以便了解更多信息。 请参阅proc(5)手册页。
试着把你的简单程序弄清楚它正在做什么系统调用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。