Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linked lists issue

Tags:

c

linked-list

I have this code:

#include "stdlib.h"
#include "stdio.h"

typedef struct lista TLista;
struct lista{
  char dado;
  TLista* prox;
}lista;

TLista* insere(TLista* l, char dado){
  TLista* aux;
  TLista* anterior;
  if(l == NULL){
    l = (TLista*) malloc(sizeof(TLista));
    l->dado = dado;
    l->prox = NULL;
  }else{
    aux = l;
    while(aux != NULL){
      anterior = aux;
      aux = aux->prox;
    }
    aux = (TLista*) malloc(sizeof(TLista));
    anterior->prox = aux;
    aux->dado = dado;
    aux->prox = NULL;
  }
  return l;
}

void imprime(TLista* l){
  if(l == NULL){
    printf("A lista esta vazia");
  }else{
    while(l != NULL){
    printf("%c", l->dado);
    l = l->prox;
  }
}

void concatena(TLista* lista1, TLista* lista2){
  TLista* aux = lista1;
  if(!lista1){
    lista1 = lista2;
    printf("\nInside function: ");
    imprime(lista1);
  }else{
    while(aux->prox != NULL){
      aux = aux->prox;
    }
    aux->prox = lista2;
  }
}

int main() {
  TLista* lista1 = NULL;
  TLista* lista2 = NULL;
  printf("\n");
  lista1 = insere(lista1, 't');
  lista1 = insere(lista1, 'e');
  lista1 = insere(lista1, 's');
  lista1 = insere(lista1, 't');
  lista1 = insere(lista1, 'e');

  imprime(lista1);

  printf("\n\n\n\n");

  lista2 = insere(lista2, 'x');
  lista2 = insere(lista2, 'u');
  lista2 = insere(lista2, 'l');
  lista2 = insere(lista2, 'a');
  lista2 = insere(lista2, 'm');
  lista2 = insere(lista2, 'b');
  lista2 = insere(lista2, 's');

  concatena(lista1,lista2);
  printf("\nOutside function: ");
  imprime(lista1);
  printf("\n\n");
  return 0;
}

The functions names were written in Portuguese. So, the function concatena should merge two lists and in fact it is doing it when lista1 is not NULL, but when I comment out these lines:

  lista1 = insere(lista1, 't');
  lista1 = insere(lista1, 'e');
  lista1 = insere(lista1, 's');
  lista1 = insere(lista1, 't');
  lista1 = insere(lista1, 'e');

  imprime(lista1);

the function concatena should receive the first list as NULL and the second as xulambs. According to it, the lista1 should receive lista2's head address, but when the function ends it execution lista1 is empty.

I debugged printing the values of lista1 just after receive lista2's head address and it works well, but when got to the main function, lista1 still NULL.

Can anyone help me to figure out whats going on? thanks


A few translations:

  1. lista = list
  2. dado = data
  3. prox = next
  4. imprime = print
  5. insere = add
  6. concatena = merge
like image 978
João Lucas Gouveia Avatar asked Feb 08 '23 06:02

João Lucas Gouveia


2 Answers

The variable value of "TLista* lista1" in the main function is not modified when you pass it to another function (concatena) and modify it there.

Either you let "concatena" return a valid pointer, e.g.

lista1 = concatena(lista1,lista2);

and return lista2 from concatena in case that lista1 is NULL or you pass a pointer to your "lista1" variable to the function, e.g.

concatena(&lista1, lista2)

... in which case your concatena function would look like this:

void concatena(TLista** lista1, TLista* lista2){
  TLista* aux = *lista1;
  if(!*lista1){
    *lista1 = lista2;
    printf("\nInside function: ");
    imprime(*lista1);
  }else{
    while(aux->prox != NULL){
      aux = aux->prox;
    }
    aux->prox = lista2;
  }
}

However, handing pointers around like that is a sure way to get confused. It is easier to have a structure that maintains a pointer to the first element of your list and passing a pointer to that structure around.

like image 146
Eike Decker Avatar answered Feb 09 '23 18:02

Eike Decker


You need to pass a pointer to a pointer into your function concatena. When you pass a pointer, a local copy of it is created inside function and the function changes only a copy.

#include "stdlib.h"
#include "stdio.h"

typedef struct lista TLista;
struct lista{
  char dado;
  TLista* prox;
}lista;

TLista* insere(TLista* l, char dado){
  TLista* aux;
  TLista* anterior;
  if(l == NULL){
    l = (TLista*) malloc(sizeof(TLista));
    l->dado = dado;
    l->prox = NULL;
  }else{
    aux = l;
    while(aux != NULL){
      anterior = aux;
      aux = aux->prox;
    }
    aux = (TLista*) malloc(sizeof(TLista));
    anterior->prox = aux;
    aux->dado = dado;
    aux->prox = NULL;
  }
  return l;
}

void imprime(TLista* l){
  if(l == NULL){
    printf("A lista esta vazia");
  }else{
    while(l != NULL){
      printf("%c", l->dado);
      l = l->prox;
    }
  }
}

void concatena(TLista** lista1, TLista** lista2){
  TLista* aux = *lista1;
  if(!(*lista1)) {
    *lista1 = *lista2;
    printf("\nInside function: ");
    imprime(*lista1);
  }else{
    while(aux->prox != NULL){
      aux = aux->prox;
    }
    aux->prox = *lista2;
  }
}

int main() {
  TLista* lista1 = NULL;
  TLista* lista2 = NULL;
  printf("\n");
//  lista1 = insere(lista1, 't');
//  lista1 = insere(lista1, 'e');
//  lista1 = insere(lista1, 's');
//  lista1 = insere(lista1, 't');
//  lista1 = insere(lista1, 'e');

//  imprime(lista1);

//  printf("\n\n\n\n");

  lista2 = insere(lista2, 'x');
  lista2 = insere(lista2, 'u');
  lista2 = insere(lista2, 'l');
  lista2 = insere(lista2, 'a');
  lista2 = insere(lista2, 'm');
  lista2 = insere(lista2, 'b');
  lista2 = insere(lista2, 's');

  concatena(&lista1,&lista2);
  printf("\nOutside function: ");
  imprime(lista1);
  printf("\n\n");
  return 0;
}
like image 41
Anton Tolkachev Avatar answered Feb 09 '23 19:02

Anton Tolkachev