Concatenating two linked lists into C

Asked

Viewed 3,307 times

1

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

"Segmentation fault: 11"... 

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

Follows 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

2 answers

1

Watch this excerpt:

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

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

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

Well, if one of you is NULL, one of these two returnwill have already been hit, and therefore this third if is unnecessary because it is impossible for him to be reached when his condition is false.

However, there is a mistake of memory Leak here, for immediately before we have this:

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

If this memory allocation is done 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 this allocation is there silly, because the tmp1 = lis1; within the while below will ensure that what was allocated before will be lost. The solution is simply to allocate nothing.

In this function you still make a good mess with the pointers tmp1 and lis1, messing up the lists and losing some nodes.

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

In the main, you also do not need (at least not yet) to last1 and last2.

As a last tip, I stress that cultivate a discipline to maintain a strict identation and not tolerate the slightest deviations is good because it will avoid mistakes and confusions 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;
}

-2

Lista* concatList(Lista* a, Lista* b){

    Lista* temp = a;
    while(temp != NULL){
        b = inserirFim(b, temp->item);
        temp = temp->prox;
    }
    return b;
}
  • 1

    Explain your answer better...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.