什么导致SIGSEV?

/ *

从所有post中学习 – 请纠正我,如果我错了..

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

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

应该已经从堆中分配 – 使用malloc()…而不仅仅是一个固定大小的堆栈(程序文本)

* /

这一个SIGSEV的:

#include  #include  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  #include  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  #include  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; 

}

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

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

您应该动态创建此数组:

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

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

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

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


没有函数调用main()

 0x00001ff0 : push %ebp 0x00001ff1 : mov %esp,%eax 0x00001ff3 : mov %esp,%ebp 0x00001ff5 : sub $0x2625a10,%esp 0x00001ffb : mov %eax,%esp 0x00001ffd : leave 0x00001ffe : ret 

main()调用exit() main()

 0x00001fe0 : push %ebp 0x00001fe1 : mov %esp,%ebp 0x00001fe3 : sub $0x2625a28,%esp 0x00001fe9 : movl $0x0,(%esp) <==== This causes segfault. 0x00001ff0 : call 0x3000  

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

正如其他人所指出的那样,堆栈大小就是问题所在。 查看程序的C / C ++最大堆栈大小以获取更多详细信息。