2012-03-06 109 views
2

在C++中有一种方法可以检查内存地址是否被任何指针引用?C++:检查一个地址是否被引用

+0

你是指什么内存地址?一个对象将占用一系列的地址,指针只会指向开始。你想说'我有这块内存地址,想知道系统中有没有对象吗? – 2012-03-06 07:49:19

回答

8

不,完全没有。

(除非你做的显然跟踪自己。)

+0

简短,简单,重要! – Marlon 2012-03-06 06:58:30

+0

对于“追踪你自己”,可能是不可行的,或者更好的“不与计划指针”。 虽然你可以替换新的/删除来查看分配的内容,直到有可能做指针分配和算法的“跟踪”风险不成功(因为有操作可以绕过它) 这是可能的(在类似C的方式)在普通地址上实现Hans Bohem算法,但不可能正确销毁对象。 C++的方式应该需要一个垃圾收集指针类与垃圾收集新的(手有一个禁用删除)合作 – 2012-03-06 07:34:34

2

这将意味着C++有一个垃圾收集器或等价物,它没有。换句话说,不。

你可以利用智能(尤其是共享这个用例)指针来管理你的内存。

+0

是的...我明白智能指针是一个选项...我的项目是一个大的组成1000s的文件...用智能计数器部件替换所有的指针是简单的不合理的...只是想检查我们是否有任何其他方法来做到这一点...... Thx! – rahul 2012-03-06 06:57:28

1

这是不可能的。考虑指针算法:从给定的记忆位置,你可以增加你的方式,并到达不同的位置。这是用于跨阵列移动:从

int * a = &array[0]; 

没有人知道,如果你会做++ A,A + 3,或什么的。你可以从数组[0]开始,超出数组边界(这是没有界限的,实际上是:-))。

这是深深根植于C和C++继承它,但C++已经开发了一系列的惯用风格,试图尽量减少需要去原始指针级别。你可以阅读关于智能指针(保持指向给定资源的人数并在计数变为零时将其删除)的智能指针。在很多情况下,你可以使用std :: vector而不是数组,而不必考虑超出数组末尾的风险。

+0

这不是真正的原因。 C编译器可以将每个对象的详细信息放在一起并将其传递给运行时,以便可以计算可达的所有对象的集合。你会知道每个指针在哪里隐藏,然后你可以检查它们是否指向给定的地址。对于越界指标也是如此。如果我们可以遍历所有的数据并且到达这个变量'a'并且知道它是一个指针,我们可以将它与一个给定的地址进行比较。但是,唉,我们没有那个信息。 – Kaz 2012-03-06 07:43:18

+0

我不确定要理解你的推理:假设你有一个指针,并且你动态计算一个偏移量并将指针指向新的位置。当然,这将在系统为您的流程分配的空间中,但是如何在不设置其他位置的书籍管理机器(本质上是垃圾收集器)的情况下知道?这是可能的,但与C方式(原始指针和手动内存管理)以及C++方式(智能指针,RAII,标准libray容器)非常不同。 – Francesco 2012-03-06 10:09:12

0

在执行此操作之前,您需要实现自己的智能指针,动态内存分配或垃圾回收器。

+0

你不需要自己实现它,因为stdlib中有智能指针。不要重新发明轮子,除非你的观点是重新发明轮子。 – Griwes 2012-03-06 07:08:27

+1

好的,但不确定是否可以问他们是否有指针指向它们。 – Damian 2012-03-06 07:15:22

+0

那么,你的智能指针将为每个可寻址字节创建一个大表,并为每个可寻址字节存储指针计数器?我不这么认为。要检查地址是否指向某个东西,以及这个“有多少东西”在那里,你将不得不访问智能指针对象。跟踪指向给定字节的指针而不在智能指针中检查它会太大而无法使用。一般来说,您只需将内存管理留给智能指针并使用它们来控制内存 - 无需将计数器存储在外。 – Griwes 2012-03-06 07:30:27

0

不是。但是......


Boehm Garbage Collector非常成功地管理由悲观这样做,是考虑到任何东西,看起来像一个内存地址内存地址(而不是位域的一个随机整数或继承这恰好看起来如此)。悲观意味着某些数据的收集时间比以前要晚得多,但这对于垃圾收集器来说并不重要(并且要比收集太快!)。


在C++ 11,已经引入了一些low-level facilities缓解垃圾收集器的创建:

  • declare_reachable:声明的对象不能被回收

  • undeclare_reachable:声明可以回收物件

  • declare_no_pointers:声明的存储区域不包含可追踪的指针

  • undeclare_no_pointers:取消的std::declare_no_pointers

  • pointer_safety效果:列表指针安全模型

  • get_pointer_safety:返回当前指针安全模型

declare_no_pointers暗示对象只包含整数/ bitfi elds/whatever和no指针,这样在扫描垃圾收集器时可能会更准确。这种知识可能会影响你的情况。


然而,这一切都堕入包装技巧的。例如,通常利用64位指针具有太多位并使用其中的一些来在指针内存储标志的事实。或者相反,利用有效载荷来存储指针或整数值。显然,扫描存储器寻找指针时,这并不好,因为扫描的值与实际地址不一致。

这些技巧在Clang/LLVM或Javascript引擎(V8,SpiderMonkey等)中大量使用,例如,以及一些真正关心内存占用空间和速度的软件。


所以,总的来说,没有C和C++太宽松记忆准确地能够知道。即使std::shared_ptr不超过约定,并且可能会意外地在其他地方存储原始指针

实际上,对于您可能遇到的大多数问题都有解决方案。无论是使用类型系统和一些约定,或使用Boehm的扫描(这应该是非常罕见的...)。然而,这需要更详细的问题。

相关问题