有没有办法获得堆上先前分配内存的大小?
例如:了解堆上预留内存的大小
//pseudo-code
void* p = operator new (sizeof(int) * 3);
unsigned size = getSomeHow(p);
有没有办法获得堆上先前分配内存的大小?
例如:了解堆上预留内存的大小
//pseudo-code
void* p = operator new (sizeof(int) * 3);
unsigned size = getSomeHow(p);
你不能在任何时候都做到这一点,因为operator new()
可以在任何合理的方式过载,甚至不使用运行时堆。
如果在Visual C++中使用malloc()
实现operator new()
,则可以使用_msize()
。
尽管Sharptooth在他的回答中是正确的(新的可以被重载),但解决方案可能就在这个事实中。通过重载新的,你可以轻松地添加你自己的新的和删除的实现。在您实现新的,你应该:
delete运算符应该做相反:从指针
如果你做这种方式给出,确保实现所有类型的新和删除(投掷和不投掷,新和新[],删除和删除[],...)。
另外要小心第三方库。他们有时会把他们的编译代码中的新调用放到他们的DLL中,但是在头文件中调用删除。这意味着新的和删除将使用不同的实现,您的应用程序将崩溃。
编辑:
舍入到8个字节的倍数和相加的8个字节是必要的,因为数据应储存在一个ADDRES这是它的大小的倍数:
由于双打,我所知道的最大的原生数据类型,我们四舍五入为8个字节的倍数倍数的地址,我们增加8个字节,使确保保持这些要求。
为什么只有8个字节,而不是“足够的字节来存储'size_t'变量”? – sharptooth 2010-11-01 10:32:57
由于本地数据类型需要存储在大小为其倍数的地址上。通常,最大的数据类型是双倍的,即8个字节。因此,我们需要添加8个字节的大小和指针,以保持8个字节的倍数。 (为我的帖子添加一个小小的更正,以确保我们保留8个字节的倍数)。 – Patrick 2010-11-01 11:18:30
好的,我明白了。那么不应该是'max(sizeof(double),sizeof(void *))'或类似的东西,以便代码可以移植到1024(或其他)位计算机? – sharptooth 2010-11-01 11:52:46
new
操作者调用malloc()
和大小存储在一个全局std::map<void*, size> alloc
。那么这功能会像你想:
getSomeHow(void *p){
return alloc[p];
}
这很好,但为什么不只是分配一个更大的块,在开始时写入分配的大小并返回一个偏移量指针? – sharptooth 2010-11-01 10:31:49
嗯,是的,它实际上好多了! – Ben 2010-11-01 10:39:49
@Ben你会提供一些提示如何写我自己的malloc?它非常感兴趣。在此先感谢 – 2010-11-01 10:53:47
您的意思是,以前在函数的代码中,线程的控制流还是由您的进程在堆上分配? – einpoklum 2013-08-06 11:58:57