new/malloc 似乎如何记住分配的数据量
How do new/malloc seem to remember amount of data allocated?
为什么这不会导致内存泄漏?我在堆上分配了很长时间的空间,然后将指针更改回字符*。之后,我在此指针上调用 delete(或第二个示例中为 free)。这两个示例似乎都不会导致内存泄漏。
#include <stdlib.h>
struct leaky {
long long* testptr;
leaky() {testptr = new long long; }
~leaky() { void* newptr = (void*) testptr;
char* newptr2 = (char*) newptr;
delete newptr2; }
};
struct leaky2 {
long long* testptr;
leaky2() { testptr = (long long*) malloc(sizeof(long long)); }
~leaky2() { void* newptr = (void*) testptr;
char* newptr2 = (char*) newptr;
free (newptr2); }
};
int main() {
while (true) {
{
leaky leak = leaky();
}
}
}
我对此进行了测试:GCC 版本 4.6.3 20120306 (Red Hat 4.6.3-2) (GCC)在 Unix 系统上。
第一段代码是未定义的行为,因为您无法从与new
-ed 无关的类型中delete
。第二种情况是正确的,所以我们可以讨论这种情况。
malloc
和free
的接口是基于void*
的,所以类型在这里并不重要,但问题仍然存在:free
怎么知道分配了多少malloc
?答案是它是实现定义的。它可以通过不同的方式完成。分配器可以获取更大的内存块,并将信息存储在该额外空间中。在某些情况下,malloc
从不同的池中为不同的固定大小(特别是对于小对象)分配信息,因此不需要使用可能很小的对象来跟踪信息。在这些情况下,free
的实现只需要弄清楚内存来自哪个池并将块返回到池中。
malloc
将一些簿记信息与它返回给您的地址的值相关联(有时在地址之前的内存区域中)。 此簿记信息包含分配的大小。 转换地址不会更改此地址的值,只会更改代码对它的解释。
-
任何指向内存的指针都可以转换为
char*
并具有相同的值。 因此,强制转换为char*
只会改变编译器解释值的方式(sizeof(*ptr)
返回的内容等)。 它不会更改指针的值。 -
operator delete
和free()
接受void*
。 因此,当任何一方被要求释放内存时,任何"类型"的概念都已经消失了。 他们必须能够解释这一点,并在不知道这些字节过去是什么的情况下使用内存。作为参考,他们通常通过分配一点额外的内存并在地址返回给您之前以某些字节记录该内存的大小来做到这一点。 但这是一个实现细节;不要依赖它。
malloc 或 new 时,使用的空间由"开销"(与已用内存块和可用内存块的大小有关的信息,指向所需空间的实际指针)和"有效负载"(正在使用的内存)组成。
用于此簿记信息的一种行话形式是"初始化记录",可能类似于以下结构
struct InitRecord
{
int memBlockSize;
void* mem;
};
这就是malloc记住你使用了多少mem的方式。进一步了解的一个好方法(也是一个有趣的练习!)是创建自己的堆分配器。
很好的参考资料在这里 http://www.cs.ucsb.edu/~rich/class/cs170/labs/lab1.malloc/index.html
和这里
http://systematicgaming.wordpress.com/2008/08/05/memory-management-introduction/
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- 动态分配的聊天数组打印缺失的数据和空
- 基于浅树的数据结构的内存分配器,用于频繁分配和解除分配
- C++,在对象内分配多个数据时,堆栈分配是否更有效? 在下面的程序中,类A_Heap的效率会更低吗?
- 我想知道我是否可以将一个类分配给特定的成员数据并创建该类的实例
- 使用 delete [] 运算符取消分配类中数据成员的内存
- 如何在C 中的派生类中分配数据成员数组
- 动态分配数据类型C++
- 映射资源并在direct3d11中分配数据
- 正在为堆上的priority_queue分配数据
- C++删除堆分配数据的二进制数组-它会全部删除吗?关于删除,我应该知道些什么
- 在窗口中的特定地址分配数据
- 使用SetData()分配数据后,cvReleaseImage()出现分段错误
- c++中栈分配数据的生命周期
- 从OpenCV中用户分配数据的Mat构造函数
- 我如何知道指针是否已通过"新建"分配数据?
- 在For循环中声明多个变量,然后为这些变量分配数据
- 查找已分配数据的未执行位
- std::vector::assign-重新分配数据
- 如果我在使用新的和结束的程序分配数据后没有调用删除运算符,会发生什么情况?