【问题标题】:EXC_BAD_ACCESS(code=1, address=0x0)EXC_BAD_ACCESS(代码=1,地址=0x0)
【发布时间】:2016-09-21 01:29:00
【问题描述】:

我正在尝试从全局变量源填充结构的链接列表,但我在 strcpy() 行得到了一个 BAD_ACCESS。使用 C。想知道是否有人可以指出问题。

全局结构体声明如下:

#include "data_structs.h"
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINE_LEN   256
#define NUL        '\0'

table_entry_t reg_list[]=
{
{"R0",0},{"PC",0},{"R1",1},{"SP",1},{"R2",2},{"SR",2},{"R3",3},
{"R4",4},{"R5",5},{"R6",6},{"R7",7},{"R8",8},{"R9",9},{"R10",10},
{"R11",11},{"R12",12},{"R13",13},{"R14",14},{"R15",15},{"R16",16}
};

... 结构看起来像这样(如下)并在 .h 文件中定义。

typedef struct
{
    char label[20];
    int address;

}table_entry_t;

typedef struct
{
    table_entry_t *data;
    void *next;
} List_node_t;

typedef struct
{
    List_node_t *head;
}list_t;

链表的初始化使用:(下)。 EXC_BAD_ACCESS 出现在“strcpy(new_node->data->label,reg_list[i].label);”这一行

boolean List_init (list_t *list)
{
int all_ok = False;
int i=0;
char* temp[3];

if (list != NULL) {
    list->head = NULL;

    //Add Register Labels

    while(i<20)   // 20 register labels
    {
        List_node_t *new_node = NULL;    
        new_node = (List_node_t *) malloc( sizeof( List_node_t));
        strcpy(new_node->data->label,reg_list[i].label); <---BAD ACCESS
        new_node->data->address = reg_list[i].address; 
        new_node->next = list->head->next;
        list->head->next = new_node;
    }
    all_ok = True;
}
return all_ok;
}

欣赏新鲜的眼睛。 问候。

【问题讨论】:

  • 未分配给new_node-&gt;data
  • 分配正确new_node = malloc (sizeof *new_node); 详细解释请参阅:Do I cast the result of malloc?。您需要通过new_node-&gt;data = malloc (sizeof *(new_node-&gt;data)); 来跟踪它 永远不会忘记分配的一种方法是编写一个create_node (...) 函数,在其中分配node,以及data 中需要分配的任何指针。 (您将初始化每个所需的值作为参数传递给list_init 并传递给create_node)。 free_nodedelete_list 可以以相同的方式工作。
  • 注意,list_init 必须是 list_init (list_t **list, ...),除非您返回第一个节点地址并将其分配回调用函数中的列表地址。为什么?第一个节点的地址是list 地址。除非您传递列表的地址(即list_init (&amp;list, ...)),否则从malloc 返回的地址将永远不会反映在main 中(或者除非您的type for @ 987654341@ 是list * 并且您的返回并将第一个节点地址分配回main)
  • @DavidC.Rankin,感谢您的建议。它确实解决了这个问题。
  • 很高兴它有帮助。这是人们学习列表的主要陷阱之一。如果您更改第一个节点,您将更改 list 地址,并且必须确保您对第一个节点的更改在调用函数中反映/可用(通常为main())。当您创建第一个节点时 - 列表地址会更改,当您删除第一个节点时,您的列表地址会更改。这就是为什么您必须将列表的 address of 传递给执行任一操作(或返回并将新的第一个节点分配为列表地址)的任何函数但是,如果您删除整个列表,则不会不用担心地址。

标签: c linked-list exc-bad-access strcpy


【解决方案1】:

风格说明:C 编程世界的其余部分通常使用list_node_tListNode(分别为蛇表示法和驼峰式)。你的符号有点混乱。

您正在分配 List_node_t,但其中的 data 指针未初始化。你走运了,它是 NULL,你知道有问题。它也可能是您程序中的一个随机地址,之后任何程序行为都是可以接受的,包括您的程序是否显示一个播放俄罗斯方块的 3D 窗口。

您也可以分配它,但这很可能不是您想要做的。更好的方法是将 List_node_t 的定义更改为:

typedef struct List_node_t
{
    table_entry_t data;
    struct List_node_t *next;
} List_node_t;

我做了两个更改。第一个也是重要的一点是我将数据更改为内联,因此一个分配会同时分配数据和节点。显然,您还需要调整其余代码中访问它的语法。

第二个也有点风格,但我强烈推荐它。指向下一个的指针应该输入正确。您不能从结构定义中访问 typedef,但可以通过名称访问结构本身。为此,我为结构命名(与 typedef 相同),并用它来键入 next 指针。

【讨论】:

  • 感谢您的指点。我一直遵循我的教授符号“list_node_t”,但不知道它是标准化的。我的最终解决方案最终是两种建议的混合体。
  • @Darrell,如果您认为这回答了您的问题,请点击旁边的复选框接受答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-22
相关资源
最近更新 更多