为什么这个C程序不能让我访问内存?

时间:2019-01-01 19:08:53

标签: c debugging struct segmentation-fault dynamic-memory-allocation

我试图建立一个链表数据库,由于某种原因,该程序不允许我访问内存,或者至少这就是调试器所说的。我正在使用gdb调试器,代码块。

我已经在具有相同操作系统(Windows)的另一台计算机上编译了该程序。它运行完美,但是调试器显示了相同的错误。

void print_ListEl(ListEl* head)
{
 ListEl* current = malloc(sizeof(ListEl));
 current = head;
 if (head==NULL) exit(EXIT_FAILURE);
 if (current->next==NULL)
 {
     puts("No elements");
     return;
 }
 else
 {
     int i=1;
     while(current->next!=NULL)
     {
         printf("%d.%s\n", i, current->name);
         current=current->next;
         ++i;
     }
 }
 free(current);
}

它是这样使用的:

ListEl* element = malloc(sizeof(ListEl));
print_listEl(element);

根据调试器,这似乎会导致问题。当我看到“ current-> next”变量时,调试器会显示“无法访问地址处的内存”。如果我将current-> next更改为current,调试器仍显示与导致问题相同的功能。 ListEl结构只是带有char类型数据的常规单链列表。

 struct ListEl
 {
     char name[MAX_CHAR];
     struct ListEl* next;
 };

我也使用

typedef struct ListEl ListEl

标头使用 ifndef endif 是安全的,我已经检查了所有标头。

此功能不是在列表中没有元素时放置“ No elements”,而是喷出一些随机字符并使程序崩溃。

2 个答案:

答案 0 :(得分:2)

可能是

ListEl* current = malloc(sizeof(ListEl));
current = head;

必须

ListEl* current = malloc(sizeof(ListEl));
head = current;

否则为什么要立即执行malloc并将其丢失?


我希望您在

之前有其他代码。
if (current->next==NULL)

因为仅分配电流,而不初始化


当我看到“ current-> next”变量时,调试器会显示“无法访问地址处的内存”。

这意味着 current 已损坏,因为它已被删除,或者您从未初始化过 next 字段。问题是您不给Minimal, Complete, and Verifiable example

如果您的代码确实是这样的:

ListEl* element = malloc(sizeof(ListEl));
print_listEl(element);

element-> name element-> next 都未初始化,因此在print_listEl中是相同的

答案 1 :(得分:1)

  1. 您不应该malloccurrent。您将立即用head替换从其获得的指针,并释放分配。后面的free将释放列表的最后一个元素,但不会将前一个元素的指针设置为NULL,如果稍后使用列表,则会导致未定义的行为。

  2. 您要在此处为​​节点分配内存:

    ListEl* element = malloc(sizeof(ListEl));
    

    ,但是在调用print_listEl(element);之前,您从未设置其任何值。因此,指针element->next将不确定,并且与NULL的比较将无用。您稍后在print_listEl中取消引用此指针会导致未定义的行为。总是在malloc之后初始化:

    ListEl* element = malloc(sizeof(ListEl));
    element->next = NULL;
    memset(element->name, '\0', sizeof(element->name));