#c
#c
Вопрос:
/*Name: "Inserisci in ordine"
* Author: fra trement
* task ->
* creates a list of integers,
* in ascending order.
* Then print the list and
* free up the memory
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct nodo{
int dato;
struct nodo*next;
}nodo_t;
typedef nodo_t*Ptr_nodo;
Ptr_nodo Insinordine(Ptr_nodo l, int num); /* Insert the value in order inside the list */
Ptr_nodo destroy(Ptr_nodo list); /* Destroy the list to free HEAP */
void stampa(Ptr_nodo l); /* Print the list */
int main(){
Ptr_nodo head=NULL;;
int val;
printf("Lista di interi positivi; inserisci 0 per terminaren"); /* eng-> List of positive integers; enter 0 to finish */
do{
printf("> ");
scanf("%d", amp;val);
if(val>0){
head = Insinordine(head, val);
// printf("Inserimenton");
} else if(val==0){
printf("**FINE**n"); /* eng-> **END** */
} else {
printf("Valore non valido!n"); /* eng-> Value not valid */
}
} while (val != 0);
if(head!=NULL){
stampa(head);
// printf("PRINTEDn");
head = destroy(head);
// printf("DISTROYEDn");
} else {
printf("list: -|n");
}
return 0;
}
Ptr_nodo Insinordine (Ptr_nodo l, int num){
Ptr_nodo tmp=NULL, curr=l, prec=NULL;
int count;
tmp = (Ptr_nodo)malloc(sizeof(nodo_t));
if(tmp){
tmp->dato = num;
tmp->next = NULL;
if(l==NULL){
l=tmp;
} else {
while(curr->dato < num amp;amp; curr->next != NULL){
prec = curr;
curr = curr->next;
}
tmp->next = curr;
prec->next = tmp;
}
} else printf("Errore memorian"); /* eng-> Memory error */
}
Ptr_nodo destroy (Ptr_nodo list){
Ptr_nodo tmp;
while(list!=NULL){
tmp = list;
list = list->next;
free(tmp);
}
return NULL;
}
void stampa (Ptr_nodo l){
printf("list: ");
while(l!=NULL){
printf("%d -> ", l->dato);
l = l->next;
}
printf("n");
}
Привет, кто-нибудь может сказать мне, в чем я не прав?
Программа, кажется, работает, но как только я ввожу второе значение, появляется ошибка «ошибка сегментации (сброс ядра)».
Я хотел бы знать, является ли это ошибкой, связанной с кодом, или это проблема с памятью кучи.
введите описание изображения здесь
Надеюсь, все понятно.
Комментарии:
1. Проверьте комментарий выше, у него есть решение, в функции нет возвращаемого значения
Insinordine
. Также нет необходимости возвращать всегда NULL вdestroy
функции, вы можете сделать ее пустой функцией.2. почему вы не возвращаете обновленный
head
адресInsinordine
?3. это была ошибка, я исправил ее, но это не исправило ошибку _ «ошибка сегментации»_
4. ОТ: относительно:
typedef nodo_t*Ptr_nodo;
это очень плохая практика программированияtypedef
указателей. Такая практика просто приводит к путанице5. относительно: if(l==NULL) {l=tmp; }` Это не вставляет первый узел в связанный список. Все, что он делает, это изменяет параметр в стеке. . In
main()
, этот оператор не делает ничего полезного, потому что функция:Insinordine()
не возвращает обновленный указатель. Кроме того, ваш компилятор должен был сообщить вам об отсутствующемreturn
операторе. с:untitled1.c:68:1: warning: control reaches end of non-void function [-Wreturn-type]
Ответ №1:
Не уверен, что вы пытаетесь здесь сделать, у вашего кода также есть проблемы с логикой. Похоже, вы пытаетесь создать отсортированный связанный список, и логика кажется неверной. В любом случае, причина, по которой вы получаете segfault, заключается в том, что вы инициализировали prev
as NULL
, и если while
условие не выполняется на первой итерации, вы пытаетесь получить доступ NULL
к элементам s, что вызывает segfault.
Используйте инструменты отладки, gdb
чтобы посмотреть, что происходит. Простая проверка с помощью gdb указывает на проблему line 67
, и вы можете попытаться выяснить проблему с этого момента.
Для начала, также инициализируйтесь prev
как ваша голова.
prev = l;
Комментарии:
1. Да, мое намерение состоит в том, чтобы создать своего рода список, состоящий из множества узлов, каждый узел представляет собой структуру с целым числом и указателем на следующий узел. Я хочу вставить каждое целое число> 0 в узел и вставить узел в связанный список, но в порядке от минимального до максимального
Ответ №2:
Есть пара проблем.
- Вы не возвращаете обновленный
head
(l
в вашем случае fromInsinordine
), когда добавляете элементы в свой список. - Ваша
Insinordine
функция ошибается в поиске следующих элементов на основе их сравнения и вставки.
Я только что переименовал ваш l
with head
.
Просмотрите приведенный ниже код и вернитесь в случае каких-либо разъяснений, добавленных встроенных комментариев.
Ptr_nodo Insinordine (Ptr_nodo head, int num){
Ptr_nodo tmp=NULL, curr=NULL, prec=NULL;
int count;
tmp = (Ptr_nodo)malloc(sizeof(nodo_t));
if(tmp){
tmp->dato = num;
tmp->next = NULL;
if(head == NULL){
head = tmp;
return head;
} else {
// first check whether head->data is less than new element (num)
if( head->dato < num )
{
tmp -> next = head;
head = tmp;
return head;
}
// assign prec pointer the head
prec = head;
// curr is head -> next
curr = head -> next;
// check until you reach NULL or curr->dato > num
// there will be two outcomes of while
while( curr amp;amp; curr->dato > num ){
prec = curr;
curr = curr->next;
}
//1. if curr is NULL then we have reached the end, so add the tmp at end
if(!curr) {
prec->next = tmp;
return head;
}
//2. curr is not NULL, but curr->dato < num
// so, we store curr node(prec->next) in tmp->next and tmp in curr node(prec->next)
else {
tmp->next = prec->next;
prec->next = tmp;
return head;
}
}
} else printf("Errore memorian"); /* eng-> Memory error */
}
Комментарии:
1.Все понятно, программа работает. Спасибо !