Linked lists issue

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

Upvotes: 4

Views: 87

Answers (2)

Anton Tolkachev
Anton Tolkachev

Reputation: 41

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;
}

Upvotes: 4

Eike Decker
Eike Decker

Reputation: 102

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.

Upvotes: 4

Related Questions