4

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
3
  • I just realized how naming your variables with names you could understand will ease your life... Commented Apr 14, 2016 at 19:42
  • 1) You're including standard headers, use #include <...>. 2) Do not cast the return value of malloc. 3) Code in English. Really. 4) You have an unused global variable named lista there. Get rid of it. 5) Use whitespace (for example around if). Improves readability. 6) Use return values. concatena should return the new list. 7) When you write a function that mallocs, write one that frees, too. Commented Apr 14, 2016 at 21:06
  • Man, this code was for studyings, of course in a product I wont code in Portuguese, also the "" in include is put by the atoms editor autocomplete, also the function concatenas prototype was duty with void return value by my teacher, if I got a list return it would be much easier.About the free, again, of course in a product I would use free to free memory blocks during the execution. BTW thanks for the other tips Commented Apr 14, 2016 at 21:28

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks for the answer. This is an problem my teacher gave to us during the classes. So he demanded the function prototype just as I wrote, with no returning, unfortunately.
4

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

3 Comments

Thanks for the answer, but why if list1 is not null, when I got to the main fuction the list1 is merged with list2, and if list1 is null it dont happen?
Because if list1 isn't null you change a member of struct Tlist. It is created a copy of pointer to a whole structure and you can access and change its members and be sure that you really change them.
Got it. Thanks a lot

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.