C ++如何检查对堆内存的访问

时间:2015-05-23 08:25:05

标签: c++ pointers heap

我有以下问题。我不是,如果有可能,如何。 我想了解代码何时使用堆中分配的内存地址(对于内置的所有类型的对象和用户定义)。 例如:

char* p= new char[60];
strcpy(p,"home");  // statement A

有一种方法可以理解“语句A”是使用堆中分配的地址“p”吗? 通过重新定义operator new,我可以存储堆地址但是如何理解某些指令何时使用它们? 我想以透明的方式为用户做这件事。

非常感谢

******一个例子

char* p= new char[60];
delete [] p;
strcpy(p,"home");  // statement A

我想警告这种无效的内存访问。 要做到这一点,我必须明白strcpy正试图访问地址p,所以我可以对p的有效性进行一些测试。

2 个答案:

答案 0 :(得分:1)

请参阅:http://www.hboehm.info/gc/gcdescr.html 它是C / C ++的透明垃圾收集器。它以您描述的方式跟踪存在引用内存位置的指针:

  

在每个集合中,收集器标记可能从指针变量到达的所有对象。既然它一般不能分辨到哪里   指针变量位于,它扫描以下根段   指针:

     

寄存器。根据体系结构,这可以使用汇编代码完成,也可以通过调用类似setjmp的函数来完成   在堆栈上注册内容。堆栈。在一个案例中   单线程应用程序,在大多数平台上完成   在当前堆栈之间(近似)扫描存储器   指针和GC_stackbottom。 (对于Itanium,扫描寄存器堆栈   单独。)GC_stackbottom变量设置为高度   特定于平台的方式取决于适当的配置   gcconfig.h中的信息。请注意,当前活动的堆栈需要   要小心扫描,因为被调用者保存了客户端代码的寄存器   可能会出现在收集器堆栈框架内,这可能会在收集器堆栈框   标记过程。通过扫描堆栈的某些部分来解决这个问题   "热切地",在一个时间点有效捕捉快照。

     

静态数据区域。在最简单的情况下,这是DATASTART和DATAEND之间的区域,如gcconfig.h中所定义。但是,在   大多数情况下,这也涉及与之相关的静态数据区域   动态库。这些都是由大多数人确定的   dyn_load.c中的特定于平台的代码。

     

标记维护一个已知可访问但尚未搜索的内存区域的显式堆栈   包含指针。每个堆栈条目包含起始地址   要扫描的块,以及块的描述符。如果不   布局信息可用于块,然后是描述符   只是一个长度。 (有关其他可能性,请参阅gc_mark.h。)

你可以想象,你必须真正卷起袖子做一些极低级别的黑客来管理这个,扫描这样的记忆是一件昂贵的事情,所以我不认为你可以出于安全原因这样做来防止悬空指针。

我建议不要这么透明地尝试这样做。让用户获取句柄到你的对象,如智能指针,它会变得更容易实施垃圾收集或安全,防止悬空指针或任何你喜欢的。 C ++擅长于那些半透明的解决方案,在这些解决方案中,您可以创建感觉像指针的对象并提供相同的运算符,但可以在顶部执行任何更多操作。

答案 1 :(得分:1)

这个问题没有意义。 Strcpy认为指针指向有效内存,因此您不需要知道任何特殊内容。如果你想断言内存是有效的,请使用一个处理它的类。然后你总是可以知道内存是有效的。

在这种情况下,std :: string将是正确的选择,elsewise std :: vector或std :: shared_ptr。