简体   繁体   English

堆栈溢出 C++

[英]Stack overflow C++

This is my code.这是我的代码。 When I access dtr array in initImg function it gives a stack overflow exception.当我在 initImg function 中访问 dtr 数组时,它给出了堆栈溢出异常。 What might be the reason?可能是什么原因?

#define W 1000
#define H 1000
#define MAX 100000 
void initImg(int img[], float dtr[])
{
    for(int i=0;i<W;i++)
        for(int j=0;j<H;j++)
            img[i*W+j]=255;

    for(int j=0;j<H;j++)
    {
        img[j] = 0;
        img[W*(W-1)+j] = 0;
    }
    for(int i=0;i<W;i++)
    {
        img[i*W] = 0;
        img[i*W+H-1] = 0;
    }
    for(int i=0;i<W;i++)
        for(int j=0;j<H;j++)
        { 
            if(img[i*W+j]==0)
                dtr[i*W+j] = 0;    // <------here
            else
                dtr[i*W+j] = MAX;  // <------here
        }
}
int main()
{
    int image[W*H];
    float dtr[W*H];
    initImg(image,dtr);
    return 0;
}

This:这个:

int image[W*H];
float dtr[W*H];

Creates each a 4 * 1000 * 1000 ~ 4 MB array into the stack.在堆栈中创建一个 4 * 1000 * 1000 ~ 4 MB 数组。 The stack space is limited, and usually it's less than 4 MB.堆栈空间有限,通常小于 4 MB。 Don't do that, create the arrays in the heap using new.不要那样做,使用 new 在堆中创建 arrays。

int *image = new int[W*H];
float *dtr = new float[W*H];

Your stack probably isn't big enough to hold a million ints and a million floats (8MB).您的堆栈可能不足以容纳一百万个整数和一百万个浮点数 (8MB)。 So as soon as you try to access beyond your stack size, your operating system throws you an error.因此,一旦您尝试访问超出堆栈大小的内容,您的操作系统就会向您抛出错误。 Objects or arrays above a certain size need to be allocated on the heap - preferably using a self-managing self-bounds-checking class such as std::vector - the specific size depends on your implementation.需要在堆上分配大于一定大小的对象或 arrays - 最好使用自我管理的自我边界检查 class 例如std::vector - 具体大小取决于您的实现。

In addition to the stack overrun, you have another problem -- one which is masked by your definitions of W and H.除了堆栈溢出之外,您还有另一个问题 - 一个被您的 W 和 H 定义所掩盖的问题。

for(int i=0;i<W;i++)
    for(int j=0;j<H;j++)
    { 
        if(img[i*W+j]==0)
            dtr[i*W+j] = 0;    // <------here
        else
            dtr[i*W+j] = MAX;  // <------here
    }

Your i loop should count from 0 to H-1, rather than W-1 (and the j loop should swap as well).您的 i 循环应该从 0 计数到 H-1,而不是 W-1(并且 j 循环也应该交换)。 Otherwise your code will only work correctly if W==H.否则,您的代码只有在 W==H 时才能正常工作。 If WH you will overrun your buffers.如果 WH 你会溢出你的缓冲区。

This same problem exists elsewhere in your code sample as well.同样的问题也存在于您的代码示例中的其他地方。

You're creating giant arrays on the stack.您正在堆栈上创建巨大的 arrays。 Just use std::vector instead:只需使用std::vector代替:

std::vector<int> image(W*H);
std::vector<float> dtr(W*H);

Your stack is full.你的堆栈已满。 You can allocate memory in heap or increase the stack memory.您可以在堆中分配 memory 或增加堆栈 memory。 From what I know the maximum size is about 8MB, but this is not a very good idea.据我所知,最大大小约为 8MB,但这不是一个好主意。 The best solution is to use heap allocation or some containers (vector) available in std.最好的解决方案是使用堆分配或 std 中可用的一些容器(向量)。

You will eventually get to你最终会到达

dtr[W*W+j] = 0;   <------here

Which is much more than you have allocated.这比您分配的要多得多。

Your compiler will define the stack size.您的编译器将定义堆栈大小。 A way to get around this is to dynamically allocate your arrays using std::vector array_one(W*H).解决此问题的一种方法是使用 std::vector array_one(W*H) 动态分配 arrays。

You are trying to allocate memory from stack.您正在尝试从堆栈中分配 memory 。 the maximum memory which can be allocated using stack is complier dependent.可以使用堆栈分配的最大 memory 取决于编译器。 So try something like this to avoid this kind of exception.所以尝试这样的事情来避免这种异常。

#include <stdlib.h>
#define W 1000
#define H 1000 
#define MAX 100000 
void initImg(int img[], float dtr[]) 
{ 
for(int i=0;i<W;i++) 
for(int j=0;j<H;j++) 
img[i*W+j]=255; 

for(int j=0;j<H;j++) 
{ 
img[j] = 0; 
img[W*(W-1)+j] = 0; 
} 
for(int i=0;i<W;i++) 
{ 
img[i*W] = 0; 
img[i*W+H-1] = 0; 
} 
for(int i=0;i<W;i++) 
for(int j=0;j<H;j++) 
{ 
if(img[i*W+j]==0) 
dtr[i*W+j] = 0; // <------here 
else 
dtr[i*W+j] = MAX; // <------here 
} 
} 
int main() 
{ 
int *image = (int*)malloc(4*W*H);   //Malloc the memory....(Allocated from Heap..)
float *dtr = (float*)malloc(4*W*H);

if(image && dtr) //If none of the ptr is NULL. Means memory is allocated...
{
initImg(image,dtr); 
}
return 0; 
}

You can use new as well instead of using malloc to allocate memory from heap...您也可以使用 new 而不是使用 malloc 从堆中分配 memory ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM