3

我正在调试一个 C 代码,其中我在一个指向名为board. 我正在打印电路板有一个功能:

static void board_print(board *b){
    int i,j;
    char data;
    for (i = 0; i < size; i++) {
        for (j = 0; j < size; j++) {
            data = b->data[i * size + j];
            if(data){
                printf("X ");
            }else{
                printf("O ");
            }
        }
        printf("\n");
    }
}

这是奇怪的部分。当我最初在第一个 for 循环开始时命中断点时,一切正常,我的数据正确,所有指针都正常工作等,如下所示:

第一的

然后,我第一次进入循环,i 和 j 等于 0,并且b->data[0]应该完全有效,就像两步前一样。突然,我一踩线data = b->data[i * size + j];,数据指针就变成了一个空指针。当我执行该行时,我(显然)得到一个错误的访问错误,如下所示:

第二

可能是什么原因?我以前用过 C,而且我已经掌握了它,但是在单线程简单的 C 程序中,我从未见过指针值突然变为 null。我使用 Apple LLVM Compiler 4.1 进行编译和 lldb 进行调试,这是 XCode 4.5 的默认设置。

更新:使用 gcc 编译和使用 gdb 调试时观察到的行为相同。我身边几乎百分百的错误,但我不知道代码有什么问题..

更新#2:我现在在 gcc/gdb 上发现了一些更奇怪的东西。就在执行该行之前data = b->data[i * size + j];,我可以毫无问题地从调试器访问所有内容。在执行该行之后,我无法b->data完全访问,包括我在步进之前访问的值:

第三

在调试器中成功执行的$4 = ...行之后,我已经跨过了该行。然后我遇到了各种寻址错误,如上所示。我真的不知道发生了什么...

更新#3:我注意到一些非常奇怪的事情。在这里,首先看一下我已经实现的修复。当我完全摆脱了命名的变量时,这个开始工作没有问题data

第四

现在,仔细查看我与更新#2 一起上传的屏幕截图:在我为名为的局部变量赋值data后,b->data它的地址也发生了变化。它看起来像是作业的副作用。但我不知道背后的原因是什么。

4

1 回答 1

2

显然某事/某人改变了董事会结构的属性“数据”。

为什么 ?我只能看到三个原因:

  • 您的应用程序是多线程的,另一个线程将数据指针更新为 NULL(这不是您的情况,您只使用一个线程,抱歉没有注意到)。

  • 板结构是从堆栈中分配的,但内容不再有效......例如:返回一个局部变量的指针,但返回时变量(结构)被破坏(因为这是一个局部变量)指针...

  • 板结构是从堆中分配的,然后被释放,最后这个释放的指针仍然被使用:堆内存被其他东西破坏了......

我的猜测:第二点是一个常见的错误

所以一个简单的问题:board struct 存储在 HEAP 或 STACK 内存中?

于 2012-12-29T16:09:16.763 回答