C++如何在堆栈上动态分配内存
C++ How to allocate memory dynamically on stack?
有没有办法在堆栈而不是堆上分配内存?我找不到一本关于这方面的好书,这里有人知道吗?
使用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
然后alloca()将在每次循环时分配额外的数据大小字节。在从函数返回之前,不会释放任何alloca()字节。因此,如果nDataSize
为1024,iterations
为8,那么在返回之前将分配8千字节。如果您的nDataSize
=65536和iterations
=32768,那么您将总共分配65536×32768=2147483648字节,几乎可以肯定会破坏堆栈并导致崩溃。
轶事:如果您在缓冲区结束后写入,特别是如果您将缓冲区传递给另一个函数,并且该子函数对缓冲区的长度有错误的想法,那么您很容易遇到麻烦。我曾经修复了一个相当有趣的错误,我们使用alloca()
创建临时存储,用于在将TrueType字体字形发送到GPU内存之前渲染它。我们的字体库没有考虑瑞典语中的变音符号Å字符,所以它告诉我们在渲染之前分配n字节来存储字形,然后实际渲染n+128字节。额外的128字节写入了调用堆栈,覆盖了返回地址,并引发了一场非常痛苦的不确定崩溃!
由于这是标记为C++的,通常您只需在正确的范围内声明所需的对象。它们在堆栈上分配,并保证在作用域退出时释放。这就是RAII,也是C++相对于C的一个关键优势。不需要malloc
s或new
s,尤其是不需要alloca
s。
您可以声明一个本地char[1024]
或任何您想要的字节数(最多一点),然后取本地地址作为指向堆栈上该内存块的指针。不完全是动态的,但如果需要,您可以使用自己的内存管理器来封装这些内存。
讨论动态内存分配的文章
我们可以通过以下方式在堆栈内存上动态分配可变长度空间使用函数_alloca。此函数从程序堆栈中分配内存。它只需占用要分配的字节数,并将void*返回给正如malloc调用一样分配了空间。此分配的内存将在函数退出时自动释放。
因此,不需要明确地释放它。一个人必须牢记此处的分配大小,因为可能会发生堆栈溢出异常。堆栈溢出异常处理可用于此类调用。如果堆栈溢出异常可以使用
_resetstkoflw()
进行恢复返回因此,我们使用
_alloca
的新代码将是:int NewFunctionA() { char* pszLineBuffer = (char*) _alloca(1024*sizeof(char)); ….. // Program logic …. //no need to free szLineBuffer return 1; }
参见_malloca
。
当/如果C++允许使用(非静态)const
值作为数组边界时,会更容易。
目前,我所知道的最好的方法是通过递归。有各种各样的聪明技巧可以做到,但据我所知,最简单的方法是让你的例程声明一个固定大小的数组,并填充和操作它所拥有的。当它完成时,如果它需要更多的空间来完成,它就会自称。
您可以使用BDE C++库,例如
const int BUFFER_SIZE = 1024;
char buffer[BUFFER_SIZE];
bdlma::BufferedSequentialAllocator allocator(buffer, BUFFER_SIZE);
bsl::vector<int> dataVector(&allocator);
dataVector.resize(50);
BDE提供了全面的分配器选项以及bsl::vector等集合,这些集合可以在不更改容器类型的情况下使用多态分配器。
您也可以考虑:
- https://github.com/facebook/folly/blob/master/folly/docs/small_vector.md
- http://www.boost.org/doc/libs/1_55_0/doc/html/container/non_standard_containers.html#container.non_standard_containers.static_vector
- http://llvm.org/docs/doxygen/html/classllvm_1_1SmallVector.html
- 删除类成员的动态分配内存的最佳方法是什么
- 如果您为类的一个对象动态分配内存作为参数,会发生什么
- 为浮点数组动态分配内存
- 包含动态分配内存作为值的映射的取消定位速度有多快?
- STD分配器是否会在堆上动态分配内存?它可以安全地删除内存吗?
- 如何为const char double指针(使用新的)动态分配内存
- 在动态分配内存的同时,使用指定尺寸
- 动态分配内存
- 如何在我指向的安德烈斯上动态分配内存?
- 为什么C 没有方便的方式来为多维数组动态分配内存
- 当动态分配内存时警告
- 为结构动态分配内存
- 动态分配内存,用于存储使用 WinHttpReadData 下载的 HTML 源代码
- 如何在C++中为灵活阵列动态分配内存
- 从C++中的文件读取时动态分配内存到结构
- 在c++中的赋值运算符重载方法中删除旧的动态分配内存
- 在类方法中使用新运算符动态分配内存的寿命和范围是多少
- 以C++为单位的动态分配内存的初始值
- 虚拟析构函数:如果基类动态分配内存,基类中是否需要它
- 如何在 c++ 中使用 2-D 固定数组为 4-D 数组动态分配内存