2015-09-04 2 views
0

Я пытаюсь создать надежный LinkedList в c, и одна из проблем, с которыми я имею дело, - это инициализация.Вывод указателя на нулевой указатель?

struct node* list = malloc(sizeof(node))

очевидный способ для инициализации LLIST, но инициализирует head элемента value 0, что это не совсем то, что я хочу. У недавно инициализированного LList не должно быть никаких узлов. Вместо этого, я хотел бы сделать что-то вроде этого:

struct node* list = NULL; 

создать LLIST, а затем добавлять элементы с:

add(&list, 1); 
add(&list, 2); 

, которые в основном разыменовать &list, тест, чтобы увидеть, если это NULL , и если это так, то X в противном случае делает Y. Однако, очевидно, я чувствую срыв, и мне интересно, не потому ли, что я разыменовал указатель на нулевой указатель?

добавить()

8 void add(struct node** headRef, int value) { 
    9 struct node* node = *headRef; 
10 struct node* new_node = malloc(sizeof(*new_node)); 
11 
12 new_node->value = value; 
13 new_node->next = NULL; 
14 
15 if (node == NULL) { 
16  node = malloc(sizeof(node)); 
17  node = new_node; 
18 } else { 
19 
20  while (node->next != NULL) { 
21  node = node->next; 
22  } 
23 
24  node->next = new_node; 
25 } 
26 } 

Благодаря

+1

Как мы можем определить, не отображается ли код, где происходит ошибка seg? Если вы разыщите '& list', вы получите' list'. Это нормально. То, что вы не можете сделать, - это разделить «список». – kaylum

+0

Ну, вы, возможно, знаете, если разыменование указателя на нулевой указатель вызывает ошибку seg для одного. ** EDIT: Спасибо за редактирование Alan, это было все, о чем я просил ... можно ли разыменовать указатель на нулевой указатель. ** –

+0

Я могу отправить код, обновление ожидается ... –

ответ

1

Этот код имеет 3 задачи:

node = malloc(sizeof(node)); 
node = new_node; 

Во-первых, вы таНос неверное число байтов. Используйте шаблон node = malloc(sizeof *node);.

Во-вторых, это утечка памяти: вы указываете node в только что выделенном блоке памяти. Затем вы указываете node на объект new_node указывает на. Это не оставляет указателей на выделенный блок.

В-третьих, node является локальной переменной для вашей функции, поэтому это изменение не видно кодом вне вашей функции.

Я думаю, что вы имели в виду всю функцию, чтобы быть что-то вроде:

void add(struct node** headRef, int value) 
{ 
// Make the new node 
    struct node* new_node = malloc(sizeof *new_node); 
    new_node->value = value; 
    new_node->next = NULL; 

// If the list is empty then make the new node be the first node 
    if (*headRef == NULL) 
     *headRef = new_node; 

// Otherwise put this node on the end of the list 
    else for (struct node *ptr = *headRef; ; ptr = ptr->next) 
    { 
     if (ptr->next == NULL) 
     { 
       ptr->next = new_node; 
       break; 
     } 
    } 
} 
0

Указатель является лишь механизмом для доступа к памяти. Различные типы указателей имеют разные механизмы доступа. Целочисленный указатель считывает 4 байта, в то время как указатель символа считывает только один, когда вы его осмеливаетесь.

Для хранения чего-то вам необходимо выделить память. После выделения памяти вы можете получить доступ к ней с помощью разных указателей. Когда вы пишете:

new_node=(struct node*)malloc(sizeof(struct node)) 

это означает, что вы выделить некоторую память и доступ к нему с помощью new_node указателя.

Когда вы пишете:

node=new_node 

это означает, что узел будет указывать на то же new_node памяти в настоящее время referring.You не нужно выделять память для узла, так как вы просто получить доступ к уже выделенной памяти, используя его.

void add(struct node** headRef, int value) { 
    struct node* node = *headRef; 
    struct node* new_node = malloc(sizeof(struct node));//Always mention datatype rather than mentioning a particular value; 

    new_node->value = value; 
    new_node->next = NULL; 

    if (node == NULL) { 
     //node = malloc(sizeof(node)); //Not required as you are just accessing the pre-allocated memory; 

     *headRef = new_node; //Change the actual pointer rather than the local one; 
    } else { 

     while (node->next != NULL) { 
     node = node->next; 
     } 

     node->next = new_node; 
    } 
} 
Смежные вопросы