【问题标题】:EXC_BAD_ADDRESS when adding more local variables in C在 C 中添加更多局部变量时的 EXC_BAD_ADDRESS
【发布时间】:2011-03-31 13:24:04
【问题描述】:

所以我有一个可以运行的程序,但是当我添加更多局部变量时,它会崩溃。

添加代码:

double prMaxT, prMinT, poMaxT, poMinT, linT;

程序接收到信号EXC_BAD_ACCESS,无法访问内存。 原因:KERN_INVALID_ADDRESS 地址:0x0000000000000000 0x0000000100001411 in bst_height (bst=0x0) at bst.c:72 72 返回 bst_height_node(bst->root);

flynn_p4(7171) malloc: * 对象 0x7fff5fc00760 错误:未分配指针被释放 * 在 malloc_error_break 中设置断点进行调试 中止陷阱

所有变量:

#define SIZE 1000
#define dSIZE 500
#define RUNS 5000
#define SEARCH_WIDTH 1501
#define SEARCHES 1000000
//main()
int rands[SIZE], dels[dSIZE], srch[SEARCHES], pre_h[RUNS], post_h[RUNS], i, j, z, found = 0, total = 0;
struct timeval whole_start, whole_end;
double prMaxT, prMinT, poMaxT, poMinT, linT;
struct bst *pre_max, *post_max, *pre_min, *post_min, *linear, *trees[RUNS];

所有这些都使我的程序占用了大约 1.2MB 的内存,因此我已经解决了我能找到的所有泄漏问题。并且错误不在 gdb 认为的 bst_height_node() 中,因为如果我注释掉 doubles,一切正常。

那么 main() 可以在堆栈上拥有多少内存有限制吗?我是否超过了它?我已将大型数组移至全局空间,但并没有修复它,但最重要的是我想知道发生了什么,而不仅仅是修复。

构建环境:Mac OS X 10.6.7 - 2010 Macbook Pro 上的 gcc 4.2.1(如果相关)

//编辑: 我用 gcc 标志 -pedantic 标志解决了这个问题,它给了我:

gcc -pedantic -c -o bst.o bst.c gcc -pedantic -c -o main.o flynn_p4.c flynn_p4.c:在函数“main”中: flynn_p4.c:87:警告:ISO C90 禁止混合声明和代码 flynn_p4.c:131:警告:ISO C90 禁止混合声明和代码 gcc -pedantic -o flynn_p4 main.o bst.o

所以我在函数中途的 int 声明导致了这个,DOH!

【问题讨论】:

  • 你能把bst_height_node()的出处贴上来,看来你是free()'ing东西你没有分配。
  • 这怎么能提供 1 MB 的内存占用?您正在为 srch 分配一百万个整数,这应该是 4 MB(或 64 位上为 8 MB)。但是,如果您超出堆栈,您应该会收到不同的错误消息。您可以通过增加其中一个预定义的尺寸来轻松测试这一点。
  • 那么活动监视器一定是在骗我,无论如何,增加宏并不会破坏它,这是奇怪的部分。只添加新变量
  • 当我们在 Stack Overflow 上收到堆栈溢出问题时,我喜欢它......
  • 嗯 ...尝试初始化您的数组:int rands[SIZE] = {0}, dels[dSIZE] = {0}, ... 只是为了踢

标签: c memory-management gdb


【解决方案1】:

不知道默认的堆栈限制是多少。我不是 MacOS 用户,但考虑到底层系统是 unix,请尝试在 shell 中使用 ulimit -a 来列出进程限制。

我猜它在内核的某个地方有一个硬限制,但在达到它之前,您可以使用ulimit -s 增加您的进程堆栈限制。

(但我必须承认,如果它真的是堆栈溢出,我会期待一个不同的错误消息 - 它看起来更像是一些空指针的东西)

【讨论】:

  • 谢谢,ulimit -a 帮助我确定我已经超出了 OS X 上的堆栈
【解决方案2】:

对于像这样的数据块,我当然会在堆上分配它们。无论您是在堆栈上存储指针还是数组,这对您的代码没有太大影响,但堆栈大小的不同之处在于。是的,堆栈的大小是有限制的。

即使它确实有效,如果您(或更糟糕的是,其他人)想要回来更改这些尺寸宏怎么办?或者,如果您有两个具有大堆栈帧的函数,它们分别运行良好,但后来您决定从另一个调用其中一个?

【讨论】:

  • 这很奇怪,更改大小宏也不会导致崩溃,只有添加新变量才能做到,我什至可以添加另一个int,但它有问题
【解决方案3】:

-pedantic 标志添加到 gcc 会在函数的中途显示一个不合适的变量声明:

gcc -pedantic -c -o bst.o bst.c gcc -pedantic -c -o main.o flynn_p4.c flynn_p4.c:在函数'main'中: flynn_p4.c:87:警告:ISO C90 禁止混合声明和代码 flynn_p4.c:131:警告:ISO C90 禁止混合声明和代码 gcc -pedantic -o flynn_p4 main.o bst.o

-pedantic 本轮获胜

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多