是什么导致SIGSEGV?

时间:2014-03-19 16:03:06

标签: c

/ *

从所有帖子中学习 - 如果我错了,请纠正我。

现在有道理 - 如果我没记错的话,堆栈是一个固定的内存段 - 在程序启动时分配...而虚拟内存可以使用malloc,realloc,free ...编程调整大小/调整大小... struct指针数组 -

长尺寸= 10000000; struct foo * bar [size];

应该从堆中分配

- 使用malloc()...而不仅仅是固定大小的堆栈(程序文本)

* /

这是SIGSEV的一个:

#include <stdio.h>
#include <stdlib.h>

int main(void) {

    struct foo {
        int x;
        char s[5];
    };

    long size = 10000000;
    struct foo *bar[size];

    long i = 0;
    while (i < size) {
        printf("%ld \n", i);
        i++;
    }
}

这个工作 - 注释掉struct foo指针数组:

#include <stdio.h>
#include <stdlib.h>

int main(void) {

    struct foo {
        int x;
        char s[5];
    };

    long size = 10000000;
    //struct foo *bar[size];

    long i = 0;
    while (i < size) {
        printf("%ld \n", i);
        i++;
    }
}

这个有用 - 评论while循环:

#include <stdio.h>
#include <stdlib.h>

int main(void) {

    struct foo {
        int x;
        char s[5];
    };

    long size = 10000000;
    struct foo *bar[size];

    long i = 0;

    while (i < size) {
        //printf("%ld \n", i);
        i++;
    }

}

/ *我真正想要实现的是这个...哪个SIGSEVS - 好的,谢谢你的回复,我真的很感激... - 看看堆栈溢出并使用堆内存探索 - 谢谢你们 * /

int main(void){

struct foo {
    int x;
    char s[5];
};

long size = 10000000;
struct foo *bar[size];

long i = 0;
while (i < size) {
    bar[i] = (struct foo *) malloc(sizeof(struct foo));
    free(bar[i]);
    i++;
}
return EXIT_SUCCESS;

}

3 个答案:

答案 0 :(得分:8)

long size = 10000000;
struct foo *bar[size];

会创建一个非常大的数组,这可能会导致堆栈溢出,因此您的程序会收到SIGSEV。

您应该动态创建此数组:

struct foo *bar = malloc(size * sizeof(struct foo *));

如果这些程序不是main()中的任何函数调用,那么为什么程序正常工作?

foo的定义将导致main()在运行时拥有一个大的堆栈帧。如果你没有调用main()中的任何函数,那么这个大的堆栈帧将不会被实际分配或访问(main()的入口代码只能确保通过操作一些寄存器和内存来保留大量的内存细胞);但如果你在main()中调用一个函数,调用本身将尝试访问该main()堆栈帧中的某些地址,因为堆栈溢出,这些地址可能无效,这将导致SIGSEV被发送

如果您反汇编并比较该程序的工作版本和非工作版本,这将是显而易见的。您也可以通过逐步执行不工作main()的说明来找到它。


main()中没有函数调用:

0x00001ff0 <main+0>:    push   %ebp
0x00001ff1 <main+1>:    mov    %esp,%eax
0x00001ff3 <main+3>:    mov    %esp,%ebp
0x00001ff5 <main+5>:    sub    $0x2625a10,%esp
0x00001ffb <main+11>:   mov    %eax,%esp
0x00001ffd <main+13>:   leave  
0x00001ffe <main+14>:   ret  

exit()中致电main()

0x00001fe0 <main+0>:    push   %ebp
0x00001fe1 <main+1>:    mov    %esp,%ebp
0x00001fe3 <main+3>:    sub    $0x2625a28,%esp
0x00001fe9 <main+9>:    movl   $0x0,(%esp)    <==== This causes segfault.
0x00001ff0 <main+16>:   call   0x3000 <dyld_stub_exit>

答案 1 :(得分:3)

堆栈溢出导致sigsegv。不需要while循环。单个printf会导致堆栈溢出 在堆栈上创建局部变量。变量foo在堆栈上使用了巨大的空间。 Stack还用于存储函数调用中的返回地址。所以它们两者一起会导致堆栈溢出。 foo几乎占用了堆栈中的所有空间。调用printf溢出堆栈
您应该使用malloc在堆上进行分配。

答案 2 :(得分:1)

正如其他人所指出的那样,堆栈大小是问题所在。查看C/C++ maximum stack size of program了解详情。

相关问题