在内存中定位对象(结构) - 如何?

时间:2010-03-13 00:00:08

标签: c++ memory struct

如何在内存中找到一个对象,假设你有一个结构定义为:

struct POINT {
   int x;
   int y;
};

我如何扫描应用程序的内存区域以查找此结构的实例,以便我可以读出它们?

谢谢R。

9 个答案:

答案 0 :(得分:4)

如果没有向结构中添加类型信息,则不能。在内存中,像这样的结构只不过是2个整数,所以你不能识别它们比识别任何其他对象更好。

答案 1 :(得分:3)

你做不到。结构不存储任何类型信息(除非它们具有虚拟成员函数),因此您无法将它们与任何其他sizeof(POINT)字节块区分开来。

为什么不将你的积分存储在矢量中?

答案 2 :(得分:2)

你做不到。您必须知道布局才能知道内存的哪个部分必须代表变量。这是一种协议,这就是我们使用基于文本的语言而不是原始值的原因。

答案 3 :(得分:2)

你没有 - 你如何将两个任意整数与随机噪声区分开来?

(但在源代码中给出Point p;,您可以使用address-of运算符获取其地址... Point* pp = &p;)。

答案 4 :(得分:2)

简短的回答:你做不到。任何(适当对齐的)8字节序列都可能代表POINT。实际上,一组int将与POINTS数组无法区分。在某些情况下,您可以利用编译器实现的知识来做得更好。例如,如果结构具有虚函数,则可以查找正确的vtable指针 - 但也可能存在误报。

如果要跟踪对象,需要在构造函数中注册它们并在析构函数中注销它们(并支付性能损失),或者给它们自己的分配器。

答案 5 :(得分:1)

无法识别该结构。您需要将结构放在可以找到的位置,堆栈或堆上。

有时,数据结构会标记有识别信息,以协助调试或内存管理。作为数据组织的一种手段,它是最糟糕的方法之一。

您可能需要对内存管理进行大量阅读。

答案 6 :(得分:1)

没有标准的方法可以做到这一点。平台可以指定一些API,允许您访问堆栈和免费存储。此外,即使您没有任何其他信息,您如何确定您正在阅读POINT对象而不是几个int?编译器/链接器可以读取它,因为它处理(尽管是虚拟的)地址并且具有比您更多的信息(和控制)。

答案 7 :(得分:1)

你做不到。在某些“标记”架构中也可能出现这样的情况,该架构也支持标记用户定义类型的对象。但是在传统架构上,通过查看原始内存内容,绝对不可能确定存储在内存中的内容。

通过在类型中引入唯一签名,您可以更接近实现您想要的目标,例如

struct POINT { 
   char signature[8];
   int x; 
   int y; 
}; 

并小心地将其设置为POINT类型的每个对象中的某个固定和“唯一”模式,然后在内存中查找该模式。如果它是您的应用程序,您可以确定该模式的每个实例都是您的POINT对象。但总的来说,当然,永远不会保证你发现的模式属于你的对象,而不是纯粹意外地存在。

答案 8 :(得分:1)

其他人所说的都是真的。在内存中,你的结构只是几个字节,没有什么特别可以区分它。

但是,如果您觉得有点黑客攻击,可以查看C库的内部结构,找出存储在堆上的位置以及它的显示方式。例如,this link显示了在一个特定系统中如何分配内容。

有了这些知识,您可以扫描堆以查找sizeof(POINT)分配的块,这将大大缩小搜索范围。如果您查看表格,您会发现正在记录malloc()来电的文件名和行号 - 如果您知道源代码中的哪个位置正在分配POINT,那么您可以也可以将此作为参考。

但是,如果你的结构是在堆栈上分配的,那你就不走运了。