安全分配堆栈分配的阵列

Safe allocation of stack allocated array

本文关键字:分配 阵列 堆栈 安全      更新时间:2023-10-16

我很难看到如何在C++中安全地分配堆栈定位数组。

通常人们会这样做:

int a[hugeNumber]{0};  //declare,allocate,inti to 0.

由于堆栈溢出,这很容易失败。

我想以某种方式拆分声明和分配,并尝试捕获分配。

显然,这是行不通的,因为该数组在 try 之外是无法访问的。

try{
int a[hugeNumber];
}
catch(std::bad_alloc& e)
{
}
//code here can't use a because of scope.

如果您只能通过分离声明和分配以安全的方式分配基于堆的数组,那么基于堆栈的数组将无法被生产代码使用,不是吗?

我认为这主要是一种心理锻炼。我一直在考虑这个问题,我没有看到任何地方说明这一点。现实中的巨数是相对的。实际上,即使是正常的数字也可能导致分配失败,并且由于似乎没有一种方法可以安全地分配基于堆栈的数组,我问的是显而易见的......"基于堆栈的数组可以在生产代码中使用吗?" 我问只是以防万一有一些我不知道的语法。我非常感谢您的投入。

实际上,即使是正常的数字也会导致分配失败,并且由于似乎没有办法安全地分配基于堆栈的数组,我问的是显而易见的......

这适用于所有自动变量,而不仅仅是数组。如果您不能确定是否有足够的堆栈内存用于"正常"大小的数组,那么如何确定是否有足够的内存用于单个对象?

堆栈内存是有限的,但与"正常"大小的对象和数组相比,它仍然很大。

基于堆栈的数组可以在生产代码中使用吗?

确定。自动数组可以在生产代码中使用,就像任何自动对象都可以(实际上必须)在生产中使用一样。您根本无法使用巨大的自动对象。

自动对象的实际大小限制究竟在哪里,在很大程度上取决于具体情况。您使用的自动存储越多,分析使用的最大堆栈大小就越相关。

为了避免生产中的堆栈溢出,应在部署之前进行测试。如果堆栈溢出发生在测试运行中,有些工具将检测堆栈溢出。


显然,这是行不通的,因为该数组在 try 之外是无法访问的。

try{
int a[hugeNumber];
}
catch(std::bad_alloc& e)
{
}

它也不会起作用,因为堆栈溢出不会引发异常。


我问只是以防万一有一些我不知道的语法。

没有语法可以"尝试"分配自动对象(包括数组)。C++也无法检查有多少内存可用于自动存储,尽管可能有系统特定的方式。

我想以某种方式拆分声明和分配,并在尝试捕获中分配。

这需要使用new进行动态分配,例如:

int *a = nullptr;
try
{
a = new int[hugeNumber];
}
catch(const std::bad_alloc &e)
{
... 
}
...
delete[] a;

或:

std::vector<int> a;
try
{
a.resize(hugeNumber);
}
catch(const std::bad_alloc &e)
{
... 
}
...