我有以下问题。我不是,如果有可能,如何。 我想了解代码何时使用堆中分配的内存地址(对于内置的所有类型的对象和用户定义)。 例如:
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的有效性进行一些测试。
答案 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。