在C中获取分段错误

时间:2016-01-15 01:22:51

标签: c segmentation-fault

在我的C代码中,我遇到了一个我无法弄清楚的分段错误。有谁知道问题是什么?

#include <stdio.h>
#include <time.h>   

#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))

int main() {    
    printf("a");
    time_t start_t, end_t;
    double diff_t;
    time(&start_t);

    int width = 440;
    int height = 280;
    int w = 25;
    int b = 15;
    int oo = 5;
    int pheight = 70;

    int m1, m2, m3, m4;
    double *points;
    printf("a");
    int data[2][width][height][width][height][height];
    printf("b");
    int side, ballx, bally, oballx, obally, py;

    for (side = 0; side < 2; side++) {
        for (ballx = w; ballx < width - w - b; ballx++) {
            for (bally = 0; bally < height - b; bally++) {
                if (side == 1) {
                    m1 = MAX(w, ballx - oo);
                    m2 = MIN(width - w - b, ballx);
                } else {
                    m1 = MAX(w, ballx);
                    m2 = MIN(width - w - b, ballx + oo);
                }
                for (oballx = m1; oballx < m2; oballx++) {
                    m3 = MAX(0, bally - oo);
                    m4 = MIN(height - b, bally + oo);
                    for (obally = m3; obally < m4; obally++) {
                        for (py = 0; py < height - pheight; py++) {
                            time(&end_t);
                            diff_t = difftime(end_t, start_t);
                            printf("side %d ballx %d bally %d oballx %d obally %d py %d time %f",
                                   side, ballx, bally, oballx, obally, py, diff_t);
                        }
                    }
                }
            }
        }
    }
    return 0;
}

2 个答案:

答案 0 :(得分:4)

似乎这可能不是导致问题的原因,但值得一提的是,data mega数组显然对于您的环境的堆栈大小来说太大了,因此您的程序导致堆栈溢出

它使用33999257600000(假设sizeof(int)为4,几乎肯定是)字节或31664GB,即使在堆上分配也很多,

#include <stdlib.h>

int main(void)
{
    char *example;
    example = malloc(33999257600000);
    if (example == NULL)
        fprintf(stderr, "Impossible to allocate so much memory\n");
    free(example);
    return 0;
}

上面的代码会在几乎所有机器上打印Impossible ...,例如64GB内存。

答案 1 :(得分:2)

不确定为什么用这种方式定义data

int data[2][width][height][width][height][height];

但是虽然data函数中没有使用main,但编译器会生成代码以尝试从自动存储(也称为堆栈)中分配它。这太大了,所以你调用了未定义的行为。

你的第一个和第二个printf没有进入控制台,很可能是因为你没有在崩溃前手动刷新stdout。每次调试fflush(stdout);后尝试printf

请注意,使用以_t结尾的变量名称(例如start_tend_tdiff_t会让人感到困惑。此后缀通常保留用于类型。

另外请注意,将屏幕放大可能会解决问题:

int width = 8192;
int height = 4096;

会使data如此之大,以至于其大小将溢出64位并归结为0个字节。编译器可能会注意到溢出和抱怨,或者只是生成代码来分配0个字节并且运行顺畅......两个都接受了未定义行为的实例。