【问题标题】:Error: "Access not within mapped region at address" (Valgrind)错误:“访问不在地址的映射区域内”(Valgrind)
【发布时间】:2018-11-10 16:49:34
【问题描述】:

我有一个 valgrind 的探针给我一个错误,说“访问不在地址 0x8 的映射区域内”。然后它说“在 0x400606: append_linked_list (testing2.c:64) by 0x400563: main (testing2.c:32)”。第 64 行是list->tail->next = newNode;,第 32 行只是调用第 64 行在append_linked_list(list, (void *) argv[i]); 中的函数。当我运行程序时,我只是将其运行为“./testing 这是一个相当短的测试字符串。”。有谁知道为什么 valgrind 给我这个错误?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef struct Node
{
    void *data;
    struct Node *next;
    struct Node *prev;
} Node;

typedef struct LinkedList
{
    Node *head;
    Node *tail;
} LinkedList;

Node *initialise_node(void);
LinkedList *initialise_linked_list(void);
Node *append_linked_list(LinkedList *list, void *data);

int main(int argc, char **argv)
{
    LinkedList *list;
    int i;

    list = initialise_linked_list();


    for(i = 1; i < argc; i++) 
    {
        append_linked_list(list, (void *) argv[i]);
    }
    return 0;
}

Node *initialise_node(void)
{
    Node *node;

    node = (Node *) malloc(sizeof(Node));

    return node;
}


LinkedList *initialise_linked_list(void)
{
    LinkedList *list;

    list = (LinkedList *) malloc(sizeof(LinkedList));
    list->head = NULL;
    list->tail = NULL;

    return list;
}

Node *append_linked_list(LinkedList *list, void *data)
{
    Node *newNode = initialise_node();

    newNode->data = data;
    newNode->prev = list->tail;
    list->tail->next = newNode;    
    newNode->next = NULL;

    return newNode;

}

【问题讨论】:

  • 地址 0x8 低得可疑。仅从 Valgrind 消息的那一部分来看,该程序似乎正在取消引用无效指针。
  • 你已经初始化了list-&gt;tail = NULL;并且你正在尝试取消引用它list-&gt;tail-&gt;next = newNode;你可能需要学习如何使用tail在末尾插入节点。 append_linked_list 中缺少大量代码。

标签: c valgrind


【解决方案1】:
Access not within mapped region at address 0x8

意味着(如预期的那样)您访问不在映射段中的地址 0x8。这通常意味着您访问的是 NULL 结构指针。

在您使用调试信息重新编译时(例如,flas -ggdb

你得到:

==7797== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==7797==  Access not within mapped region at address 0x8
==7797==    at 0x4005CF: append_linked_list (delme.c:66)
==7797==    by 0x40052C: main (delme.c:33)

直接为您提供导致错误的行,即(如 cmets 中所指出的):

list->tail->next = newNode;

0x8 的值来自于 next 在结构节点内是 8 个字节,因此 &amp;((Node *)NULL)-&gt;next 是 0x8

【讨论】:

    【解决方案2】:

    “访问不在地址 0x8 的映射区域内”。然后它说“在 0x400606: append_linked_list (testing2.c:64) by 0x400563: main (testing2.c:32)”。第 64 行是 list-&gt;tail-&gt;next = newNode; [在函数 append_linked_list]

    您的 append_linked_list() 函数在列表为空的情况下被破坏,特别是 Valgrind 标识的行执行了无效的内存访问,正如 Valgrind 所说。这对您来说并不明显,但是您可以通过在调试器中研究程序的行为来自己发现它。

    具体来说,当列表为空时,其list-&gt;tail 指针为NULL,但在这种情况下,程序会尝试分配给list-&gt;tail-&gt;next。这是无效的。此外,您从来没有为list-&gt;head 分配一个非空值,这会给您以后尝试遍历列表时带来麻烦。

    当列表为空时,您要做的最简单的事情是为所需的行为编写一个特殊情况:

    if (list->tail) {
        list->tail->next = newNode;
    } else {
        // Special case: empty list
        list->head = list->tail = newNode;
    }
    

    有一些替代方法可以通过使数据结构更复杂一些来避免这种特殊情况的需要,但这将是不同答案的主题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-14
      • 1970-01-01
      • 2020-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多