Eskil
Eskil

Reputation: 41

Error: "Access not within mapped region at address" (Valgrind)

i am having a probem with valgrind givin me an error saying "Access not within mapped region at address 0x8". It then says "at 0x400606: append_linked_list (testing2.c:64) by 0x400563: main (testing2.c:32)". Line 64 is list->tail->next = newNode;, and line 32 is just calling the function which line 64 is in append_linked_list(list, (void *) argv[i]);. When i run the program i just run it as "./testing this is a fairly short test string.". Does anyone know why valgrind is giving me this error?

#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;

}

Upvotes: 4

Views: 28134

Answers (2)

OznOg
OznOg

Reputation: 4732

Access not within mapped region at address 0x8

Means (as expected) that you access the address 0x8 which is not in a mapped segment. This usually means you access a structure pointer which is NULL.

In you recompile with debug info (flas -ggdb for example)

you get:

==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)

which directly gives you the lines that causes the error, which is (as pointed in comments):

list->tail->next = newNode;

the 0x8 value comes from the fact that next is 8 bytes inside the structure Node, thus &((Node *)NULL)->next is 0x8

Upvotes: 4

John Bollinger
John Bollinger

Reputation: 181008

"Access not within mapped region at address 0x8". It then says "at 0x400606: append_linked_list (testing2.c:64) by 0x400563: main (testing2.c:32)". Line 64 is list->tail->next = newNode; [in function append_linked_list]

Your append_linked_list() function is broken for the case in which the list is empty, and in particular, the line identified by Valgrind performs an invalid memory access, just as Valgrind says. That not being evident to you, you could nevertheless have discovered it for yourself by studying the program's behavior in a debugger.

Specifically, when the list is empty, its list->tail pointer is NULL, yet in that circumstance the program attempts to assign to list->tail->next. This is invalid. Moreover, you fail to ever assign a non-null value to list->head, which will cause you trouble later, when you try to traverse the list.

The simplest thing for you to do would be to write a special case for the needed behavior when the list is empty:

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

There are alternatives that avoid the need for such special cases by making the data structure a little more complex, but that would be the subject of a different answer.

Upvotes: 1

Related Questions