【问题标题】:C++ - Memory leaks: where is the pointer (meta) information stored?C++ - 内存泄漏:指针(元)信息存储在哪里?
【发布时间】:2011-07-28 09:25:16
【问题描述】:
这是一个我找不到任何答案的基本问题。
给定下一个代码,会发生内存泄漏:
int main(){
A* a = new A();
// 1
}
//2
假设 a 得到了值 1000。也就是说,堆上的地址 1000 现在被 A 对象占用。在 1 上,a == 1000 和在 2 上 a 超出范围。但是缺少一些信息。
在现实生活中,地址 1000 是内存中一个字节的地址。这个字节没有信息,它存储有价值的信息。
我的问题:
谁保存这些信息?
如何保存这些信息?
哪个组件“知道”指针 a 指向的位置?计算机如何知道 a 指向 sizeof(A) 个字节?
谢谢!
【问题讨论】:
标签:
c++
memory
memory-leaks
【解决方案1】:
- 此信息保存在您的程序中,变量
a
- 编译器在编译时知道这一点。运行时只有分配器知道“在这个特定地址
sizeof(A) 字节被保留” - 你不能使用该信息,你只是希望将这些字节视为包含A
【解决方案2】:
语言标准没有说。
我们所知道的是,如果我们执行delete a,内存会再次被释放。
有几个选项,例如从地址为 1000 到 1000+x 的某个内存池中分配 sizeof(a) 的所有内容。或者某人(语言运行时或操作系统)可以在某处保持餐桌。或者别的什么。
【解决方案3】:
通常 new 和 delete 运算符是在 malloc 和 free 之上实现的,尽管未指定此细节。 malloc 和 free 都指向一个数据结构,该结构跟踪哪些内存区域已分配,哪些未分配,以及每个区域有多大。 Knuth's Art of Computer Programming Vol 1 很好地描述了一些分配器设计。
【解决方案4】:
- 内存地址存储在变量
a中。
- 它只是作为一个值保存在堆栈中,就像任何其他局部变量一样。只是一个普通的旧数字,指的是存储 A 对象的内存位置。
- 编译器知道
a的类型是A*。所以它知道a中保存的位置的对象应该是一个A对象。这就是为什么如果您在该位置有其他对象会出现问题。生成的机器代码将就好像一个 A 对象在那里一样,所以如果不存在(也许那里有一个派生类),那么它必须被构建为能够生存它(在派生的情况下是虚拟函数表类)。
一旦本地指针超出范围,它将从堆栈中取出。如果这是指向堆上对象的唯一指针,那么您就失去了删除它的任何方法。这就是你得到内存泄漏的原因。突然之间,您不再知道对象在哪里,因为您丢失了唯一的指针。