SIGSEGV 在堆上的巨大数组上(我想是的)

SIGSEGV on huge array on heap (I think so)

本文关键字:巨大 SIGSEGV 数组      更新时间:2023-10-16

使用具有巨大数组的sigsegv有问题。正如我发现的那样,在堆栈上分配通常是问题。但是我在堆上分配这个数组,但仍然得到了 SIGSEGV。我不确定出了什么问题。

#include <cstdio>
using namespace std;
#define DATA_SIZE 1000000
static int inputArray[DATA_SIZE];
int* CountOnes(int* data)
{
    int outputArray[DATA_SIZE];
    int count, i;
    for (i = 0; i < DATA_SIZE; i++)
    {
        count = 0;
        while (*(data + i) > 0)
        {
            if (*(data + i) & 0x01)
                count++;
            *(data + i) >>= 1;
        }
        outputArray[i] = count;
    }
    return outputArray;
}
int main()
{
    CountOnes(inputArray);
    return 0;
}

我尝试使用静态全局数组、全局数组、使用 new 分配的数组进行分配。有什么想法吗?

您的outputArray仍在堆栈上分配。使用 ulimit -s unlimited 删除默认堆栈大小限制。另请注意,您将从 CountOnes 返回指向堆栈数组的指针。这是行不通的,因为数组在退出函数时被销毁,因此返回的指针变得无效。应将outputArray设置为静态,或使用 new 运算符分配它。

正如我发现的那样,在堆栈上分配通常是问题。

事实上,在大多数平台上,堆栈非常小(通常从几十千字节到几兆字节),并且如果您创建大型自动对象,则很容易溢出。具体来说,outputArray(可能)是四兆字节,(可能)太大了。

我尝试使用静态全局数组、全局数组、使用 new 分配的数组进行分配。

其中任何一个都应该工作,但存在其他问题 - 静态数组(本地或全局)会阻止重入和线程安全,new需要您跳过箍才能正确删除数组。最好的选择是std::vector<int>,一个动态数组,它自动管理其(堆分配的)内存。