Cra*_*rks 43
使用alloca()
(有时称为_alloca()
或_malloca()
),但要非常小心 - 当你离开一个函数时,它会释放它的内存,而不是当你超出范围时,如果你在循环中使用它,你会很快爆炸.
例如,如果你有一个像这样的功能
int foo( int nDataSize, int iterations )
{
for ( int i = 0; i < iterations ; ++i )
{
char *bytes = alloca( nDataSize );
// the memory above IS NOT FREED when we pass the brace below!
}
return 0;
} // alloca() memory only gets freed here
Run Code Online (Sandbox Code Playgroud)
然后alloca()将每次循环分配一个额外的 nDataSize字节.在从函数返回之前,所有alloca()字节都不会被释放.因此,如果你有一个1024和一个8,你将在返回之前分配8千字节.如果你有一个= 65536和= 32768,你将分配总计65536×32768 = 2,147,483,648字节,几乎肯定会炸毁你的堆栈并导致崩溃.nDataSize
iterations
nDataSize
iterations
轶事:如果你写过缓冲区的末尾,你很容易陷入麻烦,特别是如果你将缓冲区传递给另一个函数,并且该子函数对缓冲区的长度有错误的想法.我曾经修复了一个相当有趣的错误,我们用它alloca()
来创建临时存储,以便在将它发送到GPU内存之前呈现TrueType字体字形.我们的字体库在计算字形大小时没有考虑瑞典Å字符中的变音符号,所以它告诉我们在渲染之前分配n个字节来存储字形,然后实际渲染n +128个字节.额外的128个字节写入调用堆栈,覆盖返回地址并导致非常痛苦的不确定性崩溃!