The linked list does not point to NULL at the end

3

I have a problem with the following program. This consists of adding elements to a linked list in an increasing way, that is, the elements will be sorted in the list from least to greatest, with the lowest value being the "head" of the list and the one with the highest value. in the last node, which should point to NULL.

The problem is that, by calling the showDataList function, which shows all the elements added to the list, making a tour through each node until finding the NULL value, it gives me an infinite impression of (I believe) the following memory addresses to which the last node points, and because it is not NULL, they are printed constantly.

Therefore, my question is, how could I modify the program in such a way that the last node of my list points to NULL, and in this way, I could only print the values added to my list?

Note: In the main function I added a test in which I entered values to the function enter data and then I show them explicitly, without using the function showData, to verify that the values have been saved in the list.

I hope you can help me.

#include <stdio.h>
#include <stdlib.h>

struct elementos
{
    int dato;
    struct elementos *siguiente;
};

typedef struct elementos Nodo;

void ingresarValor(Nodo **cabeza, int valor);
void mostrarDatosLista(Nodo *cabeza);

int main()
{
    int valor;
    Nodo *primero = (Nodo*)malloc(sizeof(Nodo));
    primero = NULL;


ingresarValor(&primero, 2);
ingresarValor(&primero, 4);
ingresarValor(&primero, 3);
ingresarValor(&primero, -1);
ingresarValor(&primero, 6);

printf("%d\n", primero -> dato);
primero = primero -> siguiente;

printf("%d\n", primero -> dato);
primero = primero -> siguiente;

printf("%d\n", primero -> dato);
primero = primero -> siguiente;

printf("%d\n", primero -> dato);
primero = primero -> siguiente;

printf("%d\n", primero -> dato);
primero = primero -> siguiente;

//mostrarDatosLista(primero);

return 0;
}

void ingresarValor(Nodo **cabeza, int valor)
{
    Nodo *nuevo_Nodo = (Nodo*)malloc(sizeof(Nodo));
    nuevo_Nodo -> dato = valor;
    nuevo_Nodo -> siguiente == NULL;

if(*cabeza == NULL)
{
    *cabeza = nuevo_Nodo;
}
else if(nuevo_Nodo -> dato > (*cabeza) -> dato)
{
    Nodo *anterior = *cabeza;
    Nodo *p = *cabeza;

    while(nuevo_Nodo -> dato > p -> dato)
    {
        anterior = p;
        p = p -> siguiente;
    }

       anterior -> siguiente = nuevo_Nodo;
       nuevo_Nodo -> siguiente = p;
    }

    else
    {
      nuevo_Nodo -> siguiente = *cabeza;
      *cabeza = nuevo_Nodo;
    }
}

void mostrarDatosLista(Nodo *cabeza)
{
    while(cabeza != NULL)
    {
        printf("%8d\n", cabeza -> dato);
        cabeza = cabeza -> siguiente;
    }
}
    
asked by Jesús Fragoso 18.03.2018 в 05:27
source

1 answer

4

Your program has two errors. One of quite treacherous syntax. The other one of concept.

Syntax error

The syntax error is precisely when you try to assign the value NULL to nuevo_Nodo -> siguiente , since instead of an assignment you are making a comparison. Look at your code:

Nodo *nuevo_Nodo = (Nodo*)malloc(sizeof(Nodo));
nuevo_Nodo -> dato = valor;
nuevo_Nodo -> siguiente == NULL;

The == should be a single = . The compiler has not given you an error in that line because syntactically it is valid, although it does not do what you want. It is simply an expression whose result is a Boolean that you do not assign to any other variable afterwards. The C allows a line to be an expression without more, and that its result is not assigned to any site. It is equivalent to having a line in a program that says:

3*(2+2);

These types of errors can be "caught" in time if you compile with the option -Wall (I assume that you use gcc , but look at your compiler which is the equivalent option to show all warning levels ).

In fact, that's how I discovered this error, because I tried to compile your code with that flag and it jumped me:

ej.c: In function ‘ingresarValor’:
ej.c:52:5: warning: statement with no effect [-Wunused-value]
     nuevo_Nodo -> siguiente == NULL;

Concept error

Once that error was fixed, when executing the program it immediately gave me a segmentation fault , which means that at some point you try to dereference a null pointer. Compiling with debug option ( -g ) and executing the program with gdb , I discover that the line given by the segfault is the one I indicate in the following code, of the function ingresarValor() :

Nodo *anterior = *cabeza;
Nodo *p = *cabeza;

while(nuevo_Nodo -> dato > p -> dato) // <------ AQUI ROMPE
{
    anterior = p;
    p = p -> siguiente;
}

In this case it is an error in the logic of the program since what you want is to look for the element of the list in front of which you have to insert the new value, but ... what happens if you reach the end of the list ? In that case p = p->siguiente will store NULL in p and when the condition of the while attempt to look p->dato , access to a null memory address will occur causing the segfault.

The condition of the while should also verify that p is not NULL . The most succinct way to achieve this is to change it like this:

while(p && nuevo_Nodo -> dato > p -> dato)
{
    anterior = p;
    p = p -> siguiente;
}

The condition p is "true" if p is not NULL , and in that case it will continue verifying what is after the && . If p is NULL , it will no longer look at what is behind the && because the expression will be false anyway, and so it will come out of the loop.

With that change I have verified that the program now works correctly.

    
answered by 18.03.2018 / 13:18
source