Во время выполнения — ошибка сегментации (сброс ядра) — malloc

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

Есть пара проблем.

  1. Вы не возвращаете обновленный head ( l в вашем случае from Insinordine ), когда добавляете элементы в свой список.
  2. Ваша 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.Все понятно, программа работает. Спасибо !