2016-10-05 4 views
0

Я не слишком уверен, почему этот код не создает связанный список с 5 узлами, каждый из которых имеет целочисленное значение. В настоящее время я получаю segfault, и я прокомментировал строку, где происходит ошибка. Любая помощь будет оценена, спасибо.инициализировать связанный список с узлом головки с двумя указателями C++

struct node{ 
    int val; 
    node * next; 
} 

int main(){ 
    node ** head; 

    for(int i = 0; i < 5; i++){ 
     node * temp = new node; 
     temp->val = i; 

     (*head)->next = temp; //segfault here 
    } 
} 
+2

Почему именно «head» является указателем на указатель? – user4407569

+0

Инициализация 'head' - это, вероятно, хорошая идея, а не просто ее использование. Отмена ссылки на неинициализированный указатель = сбой. – tadman

+0

Как вы думаете, '' (* head) 'будет делать? – GManNickG

ответ

1

head не нужно быть указателем на указатель. Он может просто быть указателем на другой node, который всегда является первым node в вашем связанном списке. head также следует инициализировать до null.

+0

С моей реализацией это должны быть любые идеи? – Gonez

+0

Вы все равно можете использовать свой двойной указатель, вам просто нужно убедиться, что 'head' указывает на что-то, прежде чем пытаться называть' (* head) -> next', вот где происходит ваш segfault. Ваш код как написанный не будет создавать связанный список в любом случае и требует дальнейшего изучения. – Jesse

0

Попробуйте это, он должен работать. Вам все еще нужно написать код для выделения памяти.

struct node{ 
    int val; 
    node * next; 
}; 

int main(){ 
    node * head = new node(); 
    head->val = 999; 
    node *curr=head; 

    for(int i = 0; i < 5; i++) { 
     node* temp = new node(); 
     temp->val = i; 
     cout << "adding node " << i << endl; 
     curr->next = temp; //segfault here 
     curr = curr->next; 
    } 
    return 0; 
} 
+0

Спасибо за ваш ответ. Кемин Чжоу. Я понимаю, что использование одного указателя будет работать, но что касается реализации моей функции вставки в отношении эффективности, мне нужна голова, инициализированная как двойной указатель. – Gonez

+0

Вы имеете в виду, что голова - это массив указателей узлов. Вы уже работаете с указателями без двойного указателя, который должен быть очень эффективным. –

1

В вашем коде head является двойной стрелкой. Указатель, на который указывает head, не имеет построенного объекта и может быть null, следовательно, ваша ошибка сегментации.

Я бы порекомендовал вам простой указатель вместо двойного указателя, поскольку это необязательно.

+0

Спасибо за ответ wuoix, мне нужно использовать двойной указатель для моей реализации, любые другие идеи? – Gonez

+1

Одна из проблем, о которых стоит подумать, пока ваша 'head' не всегда указывает на первый элемент, вы никогда не сможете правильно построить следующий элемент без потери элементов, которые вы создали в прошлом. – wuoix

0

Первое, что вы пытаетесь сделать в своей программе с помощью «node ** head» - это разыменовать его, что, учитывая, что голова является указателем неинициализированного значения, скорее всего, приведет к краху вашей программы, если вы попытаетесь коснуться любых данных в этом месте. Правильнее всего было бы установить * head = temp, прежде чем пытаться перейти к следующему.

Кроме того, вам не нужно инициализировать список, используя двойной указатель, чтобы позднее использовать алгоритм вставки двойного указателя. Вы всегда можете сказать Узел ** head_pp = & голова и оттуда.

Прямо сейчас, ваш код выглядит так.

Node ** головка (хранит что-нибудь, так как неинициализированные)

* голова
(неинициализированная память)

(* голова) -> следующего (пытается прикоснуться неинициализированный адрес памяти, ОС убивает программу)

Следует отметить, что в большинстве случаев вы получите ошибку segfault, так как большинство uninit memory содержит 0. В конце концов вы увидите нарушение прав доступа, хотя