Concatenating two linked lists in C

1

I'm starting my studies on dynamic structures in C and I'm having trouble making a code to concatenate two lists. The part of painting on the screen the contents of the lists is working, but at the time of concatenating it appears

"Segmentation fault: 11"... 

Feel free to make suggestions on other parts of the code.

Follow the code:

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

typedef struct LinkedNode LinkedNode;
struct LinkedNode{
int data;
LinkedNode* next;
};

LinkedNode* concatena(LinkedNode* lis1, LinkedNode* lis2){

LinkedNode* tmp1 = malloc(sizeof(LinkedNode));

if(lis1==NULL){
return lis2;
}

if(lis2==NULL){
return lis1;
}

if(lis1!=NULL && lis2!=NULL){
while(lis1!=NULL){
tmp1 = lis1;
lis1 = lis1->next;
}
tmp1->next = lis2;
}

return tmp1;
}

void printList(LinkedNode* curr){
while(curr!=NULL){
    printf("%d ", curr->data);
    curr = curr->next;
}

printf("\n");
}

int main(){

LinkedNode* first1 = malloc(sizeof(LinkedNode));
LinkedNode* second1 = malloc(sizeof(LinkedNode));
LinkedNode* first2 = malloc(sizeof(LinkedNode));
LinkedNode* second2 = malloc(sizeof(LinkedNode));
LinkedNode* last1 = NULL;
LinkedNode* last2 = NULL;

first1->data = 1;
first1->next = second1;
second1->data = 2;
second1->next = NULL;
last1 = second1;

first2->data = 3;
first2->next = second2;
second2->data = 4;
second2->next = NULL;
last2 = second2;

printf("Lista 1: ");
printList(first1);
printf("Lista 2: ");
printList(first2);

free(first1);
free(first2);
free(second1);
free(second2);

printList(concatena(first1, first2));

return 0;

}//fecha o programa
    
asked by anonymous 27.02.2018 / 03:57

2 answers

1

Note this section:

if(lis1==NULL){
return lis2;
}

if(lis2==NULL){
return lis1;
}

if(lis1!=NULL && lis2!=NULL){

Now, if one of the two is NULL , one of these return s has already been reached, and therefore, this third if is unnecessary, since it can not be reached when its condition is false.

However, there is a memory leak error here, because immediately before we get this:

LinkedNode* tmp1 = malloc(sizeof(LinkedNode));

If this memory allocation is made with any of the lists being NULL , that allocated node will not be placed anywhere and the reference to it will be lost without the memory allocated by it being released. However, when analyzing the logic of this function, you do not need to allocate anything, and that allocation is there silly, since% of% within%% of% below will ensure that what was allocated before will be lost. The solution is to simply not allocate anything.

In this function you still make a good mess with the tmp1 = lis1; and while pointers, cluttering the lists and losing some nodes.

Finally, in the tmp1 function, you will call lis1 using nodes that correspond to memory that has already been deallocated with main . Never use a pointer that has already been passed to printList . The workaround is to put free only at the end.

In free , you also do not need (at least not yet) free and main .

As a last tip, I emphasize that cultivating a discipline of maintaining a strict indentation and not tolerating minimum deviations is good because it will avoid mistakes and confusion in writing and reading the code.

Follow the revised code:

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

typedef struct LinkedNode LinkedNode;
struct LinkedNode {
    int data;
    LinkedNode* next;
};

LinkedNode* concatena(LinkedNode* lis1, LinkedNode* lis2) {
    if (lis1 == NULL) return lis2;
    if (lis2 == NULL) return lis1;

    LinkedNode* tmp1 = lis1;
    while (lis1 != NULL) {
        lis1 = lis1->next;
    }
    lis1->next = lis2;

    return tmp1;
}

void printList(LinkedNode* curr) {
    while (curr != NULL) {
        printf("%d ", curr->data);
        curr = curr->next;
    }

    printf("\n");
}

int main() {
    LinkedNode* first1 = malloc(sizeof(LinkedNode));
    LinkedNode* second1 = malloc(sizeof(LinkedNode));
    LinkedNode* first2 = malloc(sizeof(LinkedNode));
    LinkedNode* second2 = malloc(sizeof(LinkedNode));

    first1->data = 1;
    first1->next = second1;
    second1->data = 2;
    second1->next = NULL;

    first2->data = 3;
    first2->next = second2;
    second2->data = 4;
    second2->next = NULL;

    printf("Lista 1: ");
    printList(first1);
    printf("Lista 2: ");
    printList(first2);

    printList(concatena(first1, first2));

    free(first1);
    free(first2);
    free(second1);
    free(second2);

    return 0;
}
    
27.02.2018 / 04:35
-2
Lista* concatList(Lista* a, Lista* b){

    Lista* temp = a;
    while(temp != NULL){
        b = inserirFim(b, temp->item);
        temp = temp->prox;
    }
    return b;
}
    
15.09.2018 / 07:29