gpt4 book ai didi

c - 是什么导致了 SIGSEGV?

转载 作者:太空宇宙 更新时间:2023-11-04 05:05:20 25 4
gpt4 key购买 nike

/*

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

现在它有意义了——如果我没记错的话,堆栈是一个固定的内存段——在程序启动时分配……而虚拟内存可以使用 malloc、realloc、free 以编程方式调整大小/调整大小……结构指针数组 -

长尺寸 = 10000000;结构 foo *bar[大小];

应该从堆中分配 - 使用 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 堆栈溢出并使用堆内存进行探索——谢谢大家*/
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。

如果您反汇编并比较该程序的工作版本和非工作版本,这将是显而易见的。您也可以通过逐条执行不工作的 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

main()中调用exit():

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>

关于c - 是什么导致了 SIGSEGV?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22511612/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com