0

嘿,我只想知道为什么每当我尝试初始化一个 512x512 数组时,总是会出现堆栈溢出错误?任何人都可以帮忙吗?下面是我的代码的一部分

CImg<float> image("lena8bit.jpg"); 
CImgDisplay main_disp(image,"Main image");

    int ImgArray [512][512];

基本上我想做的就是从图像中获取像素值并将其存储到这个数组中。图像是 512x512,因此是数组大小。

希望听到你的回答,谢谢!

4

5 回答 5

5

您的数组太大而无法在堆栈上分配。

您将不得不在堆上分配它new[](并delete[]用于释放)。

因此,您可以像这样创建数组:

// Create the array
int ** myArray = new int*[512];
for(int i=0; i<512; i++)
    myArray[i] = new int [512];

myArray[12][64] = 52; // Work with the array as you like

// Destroy the array
for(int i = 0 ; i < 512 ; i++ )
    delete [] myArray[i];
delete [] myArray;
于 2012-06-02T09:27:05.773 回答
1

我看到了两个尚未提及的解决方案。您可以使用具有静态存储持续时间的内存:

static int ImgArray [512][512];

请注意,如果将数组声明为static. 如果您计划从不同的线程多次调用该函数或者该函数是递归的,这可能是一个问题。

或者您可以从堆中分配数组并通过唯一指针管理生命周期:

std::unique_ptr<std::array<std::array<int, 512>, 512>> p
           (new std::array<std::array<int, 512>, 512>);

如果你写一个小辅助函数,语法看起来不那么复杂:

auto p = make_unique<std::array<std::array<int, 512>, 512>>();
于 2012-06-02T13:03:40.450 回答
0

答案取决于您使用的平台。例如,Microsoft Visual Studio 默认使用 1MB 堆栈大小。您可以使用 /STACK 链接器选项更改应用程序的默认堆栈大小。

在 Linux 上它有点不同,这可能会对你有所帮助

但是我认为在您的情况下使用动态内存分配更合适。

ImgArray** arr = new ImgArray* [512];
for(int i =0; i< 512; i++) arr[i] = new ImgArray[512];
于 2012-06-02T09:38:27.367 回答
0

通常,在 32 位操作系统中,每个线程的堆栈默认大小为 4K。

所以你的数组比它大。你可以做

  1. 将数组定义为未在堆栈中分配的全局或静态变量。

  2. 使用 new/malloc 在堆上分配

于 2012-06-02T09:36:30.170 回答
0

其他答案显示了您可以为不在堆栈上的二维数组中的图像分配内存的方法,但通常在处理图像时,最好使用一维数组并直接对其进行索引,例如:

const int width=512, height=512;
std::vector<int> pixels(height*width);

然后,您可以在特定坐标处找到一个像素:

// Find an x and y position:
int x=12, y=12;
int &px = pixels.at((y*width) + x);

或者找到特定像素的坐标:

// Find the x and y values of pixel 100;
int idx = 100;
x = idx % width;
y = idx / width;

这些都是简单的整数运算,通过这样做,您将只需要担心每个图像的一个连续的内存块。您可以让类似的东西std::vector以干净安全的 RAII 方式为您管理该内存。

于 2012-06-02T10:37:09.423 回答