C++ 如何在堆栈上动态分配内存?

2021-12-21 00:00:00 memory memory-management c++

有没有办法在栈而不是堆上分配内存?我找不到这方面的好书,这里有人有想法吗?

Is there a way to allocate memory on stack instead of heap? I can't find a good book on this, anyone here got an idea?

推荐答案

使用 alloca()(有时称为 _alloca()_malloca() ),但是 要非常小心 —它会在您离开函数时释放内存,而不是在超出范围时释放内存,因此如果在循环中使用它,您很快就会崩溃.

Use alloca() (sometimes called _alloca() or _malloca() ), but be very careful about it — it frees its memory when you leave a function, not when you go out of scope, so you'll quickly blow up if you use it inside a loop.

例如,如果你有一个像

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

然后 alloca() 将在每次循环中分配 额外的 nDataSize 个字节.在您从函数返回之前,所有 alloca() 字节都不会被释放.因此,如果您的 nDataSize 为 1024,iterations 为 8,您将在返回前分配 8 KB.如果您有 nDataSize= 65536 和 iterations = 32768,您将总共分配 65536×32768=2,147,483,648 字节,几乎肯定会炸毁您的堆栈并导致崩溃.

Then the alloca() will allocate an additional nDataSize bytes every time through the loop. None of the alloca() bytes get freed until you return from the function. So, if you have an nDataSize of 1024 and an iterations of 8, you'll allocate 8 kilobytes before returning. If you have an nDataSize= 65536 and iterations = 32768, you'll allocate a total 65536×32768=2,147,483,648 bytes, almost certainly blowing your stack and causing a crash.

轶事:如果你越过缓冲区的末尾写入,你很容易遇到麻烦,特别是如果你将缓冲区传递给另一个函数,并且该子函数对缓冲区的长度有错误的想法.我曾经在使用 alloca() 时修复了一个相当有趣的错误创建临时存储以在将 TrueType 字体字形发送到 GPU 内存之前渲染它.我们的字体库没有考虑瑞典语 Å 中的变音符号.在计算字形大小时,它告诉我们在渲染前分配 n 个字节来存储字形,然后实际渲染 n+128 个字节.额外的 128 字节写入调用堆栈,覆盖返回地址并导致非常痛苦的非确定性崩溃!

anecdote: You can easily get into trouble if you write past the end of the buffer, especially if you pass the buffer into another function, and that subfunction has the wrong idea about the buffer's length. I once fixed a rather amusing bug where we were using alloca() to create temporary storage for rendering a TrueType font glyph before sending it over to GPU memory. Our font library didn't account for the diacritic in the Swedish Å character when calculating glyph sizes, so it told us to allocate n bytes to store the glyph before rendering, and then actually rendered n+128 bytes. The extra 128 bytes wrote into the call stack, overwriting the return address and inducing a really painful nondeterministic crash!

相关文章