Keep one occurrence of all numbers in a linked list - c

I want to find an algorithm to keep only one occurrence of each number in a linked list using recursion
,I know recursion is not at all a good choice to solve this problem ,but I want to try it.
for more calirification:
input : 1->2->1->3->3->2->1->4
output : 1->2->3->4
Here is the program that i've made to keep only one occurrence of a given number using recursion, but i couldn't develop it in order to solve the whole problem. can I get some help? thanks in advance.
list* wipe(list* head,int val)
{
if(head==NULL) return head;
static int occ=1;
if(head->data == val)
{
if(occ-- < 1)
{
list* temp=head;
head=head->next;
free(temp);
return wipe(head,val);
}
}
head->next=wipe(head->next,val);
return head;
}

occ is set to 1 only the very time you execute the function, so from the second time (head->data == val) is true whatever val the test (occ-- < 1) will be true, this is not the right way.
You can do something like that where the list is modified to only contain unique numbers :
#include <stdio.h>
#include <stdlib.h>
typedef struct List {
struct List * next;
int data;
} List;
/* remove from l all the cells having data equals to v */
List * wipe(int v, List * l)
{
if (l == NULL)
return l;
else if (l->data != v) {
l->next = wipe(v, l->next);
return l;
}
else {
List * n = l->next;
free(l);
return wipe(v, n);
}
}
/* modify the argument to not have duplicated numbers */
void simplify(List * l)
{
while (l != NULL) {
l->next = wipe(l->data, l->next);
l = l->next;
}
}
/* helper function to construct a list */
List * mk(int v, List * n) {
List * l = malloc(sizeof(*l));
l->data = v;
l->next = n;
return l;
}
/* print the list */
void pr(List * l)
{
while (l != NULL) {
printf("%d ", l->data);
l = l->next;
}
putchar('\n');
}
int main()
{
List * l = mk(1, mk(2, mk(1, mk(3, mk(3, mk(2, mk(1, mk(4, NULL))))))));
pr(l);
simplify(l);
pr(l);
/* free the rest of the list */
while (l) {
List * n = l->next;
free(l);
l = n;
}
return 0;
}
Compilation and execution :
pi#raspberrypi:/tmp $ gcc -Wall c.c
pi#raspberrypi:/tmp $ ./a.out
1 2 1 3 3 2 1 4
1 2 3 4
pi#raspberrypi:/tmp $ valgrind ./a.out
==3988== Memcheck, a memory error detector
==3988== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3988== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==3988== Command: ./a.out
==3988==
1 2 1 3 3 2 1 4
1 2 3 4
==3988==
==3988== HEAP SUMMARY:
==3988== in use at exit: 0 bytes in 0 blocks
==3988== total heap usage: 9 allocs, 9 frees, 1,088 bytes allocated
==3988==
==3988== All heap blocks were freed -- no leaks are possible
==3988==
==3988== For lists of detected and suppressed errors, rerun with: -s
==3988== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
pi#raspberrypi:/tmp $
That way have the complexity O(n2)
A faster way is to first sort the elements in the list then remove the duplicates, allowing to have the complexity of the sort so possibly O(n*log(n)) (probably using a temporary array to sort)

If I have understood correctly you need a recursive function that appends a number to a list only in case when the number is not present already in the list.
If so then the recursive function can look for example like
int append( list **head, int val )
{
if ( *head == NULL )
{
*head = malloc( sizeof( **head ) );
int success = *head != NULL;
if ( success )
{
( *head )->data = val;
( *head )->next = NULL;
}
return success;
}
else if ( ( *head )->data != val )
{
return append( &( *head )->next, val );
}
else
{
return 0;
}
}
And if in main you have a declaration like this
list *head = NULL;
then the function can be called for example like
append( &head, val );
Or like
if ( append( &head, val ) )
{
printf( "The value %d is appended to the list.\n", val );
}

Related

Find the minimum even number in a list recursively

I've written this function:
struct nodo * MinimoPariListaRic(struct nodo * top) {
struct nodo * minimo_p = NULL; //this should be the minimum even number
//list have one or no one element
if(top) {
if(!top->next)
if(top->valore % 2 == 0) return top; // valore(italian) = value
else return NULL;
}
else return NULL;
if(top->next)
minimo_p = MinimoPariListaRic(top->next);
if (top->valore % 2 == 0)
{
if(minimo_p->valore < top->valore) return minimo_p;
else return top;
}
else return minimo_p;
}
If the list's elements are all even, the function will return the minimum, and it's ok.
But if an odd number appears, the function doesn't work correctly.
If all the numbers are odd, function should return NULL.
Because minimo_p can be NULL after the function returns from recursion if the list contains an odd integer at the last position and at least one even integer anywhere.
This line is erroneous:
if(minimo_p->valore < top->valore) return minimo_p;
You can just add the null condition here:
if(minimo_p && minimo_p->valore < top->valore) return minimo_p;
your algorithm is wrong, you can have an undefined behavior if the recursive call return NULL because setting minimo_p to NULL and you will dereference it if (top->valore % 2 == 0), and it is too much complicated, you do not need a recursive call, just to go throw the list, for instance :
struct nodo * MinimoPariListaRic(struct nodo * l) {
struct nodo * minimo_p = NULL; //this should be the minium even number
while (l != NULL) {
if (l->valore % 2 == 0) {
if ((minimo_p == NULL) || (l->valore < minimo_p->valore))
minimo_p = l;
}
l = l->next;
}
return minimo_p;
}
Because your edited topic requires a recursive call you can do for instance :
struct nodo * MinimoPariListaRic(struct nodo * l) {
if (l == NULL)
return NULL;
else {
struct nodo * minimo_p = MinimoPariListaRic(l->next);
return ((l->valore % 2 == 0) &&
((minimo_p == NULL) || (l->valore < minimo_p->valore)))
? l : minimo_p;
}
}
as you can see this is simple, I check only one times in the program if valore is odd or not etc
using a full program to check :
#include <stdio.h>
#include <stdlib.h>
struct nodo {
struct nodo * next;
int valore;
};
struct nodo * MinimoPariListaRic(struct nodo * l) {
if (l == NULL)
return NULL;
else {
struct nodo * minimo_p = MinimoPariListaRic(l->next);
return ((l->valore % 2 == 0) &&
((minimo_p == NULL) || (l->valore < minimo_p->valore)))
? l : minimo_p;
}
}
int main(int argc, char ** argv)
{
/* make a list from the args */
struct nodo * l = NULL;
while (argc > 1) {
struct nodo * r = malloc(sizeof(*r));
r->next = l;
if (sscanf(argv[--argc], "%d", &r->valore) != 1) {
puts("invalid number");
return 0;
}
l = r;
}
/* show list well made */
struct nodo * ll;
for (ll = l; ll != NULL; ll = ll->next)
printf("%d ", ll->valore);
putchar('\n');
/* */
ll = MinimoPariListaRic(l);
if (ll == NULL)
puts("no even value");
else
printf("min even value is %d\n", ll->valore);
/* free resources */
while (l) {
ll = l->next;
free(l);
l = ll;
}
return 0;
}
Compilation and executions:
pi#raspberrypi:/tmp $ gcc -Wall l.c
pi#raspberrypi:/tmp $ ./a.out 1 4 2 7 8
1 4 2 7 8
min even value is 2
pi#raspberrypi:/tmp $ ./a.out
no even value
pi#raspberrypi:/tmp $ ./a.out 3
3
no even value
pi#raspberrypi:/tmp $ ./a.out 3 3 1 5
3 3 1 5
no even value
pi#raspberrypi:/tmp $ valgrind ./a.out 3 4 5 2 0
==16881== Memcheck, a memory error detector
==16881== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==16881== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==16881== Command: ./a.out 3 4 5 2 0
==16881==
3 4 5 2 0
min even value is 0
==16881==
==16881== HEAP SUMMARY:
==16881== in use at exit: 0 bytes in 0 blocks
==16881== total heap usage: 6 allocs, 6 frees, 1,064 bytes allocated
==16881==
==16881== All heap blocks were freed -- no leaks are possible
==16881==
==16881== For lists of detected and suppressed errors, rerun with: -s
==16881== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
pi#raspberrypi:/tmp $
if you have to use recursion you should try write this down in pseudo language first:
if current list has only one element
-> return it if even, else return null
if list has more elements
get minimum of rest of list
if current element is odd
return the rest-minimum
else if rest is null
return this element
else if rest is not null
return the smaller one
I would not go with recusion on this. With really long lists you will crash your stack.
A simple loop would be even simpler and less mind bending:
init minimum to NULL
init iterator with list
while iterator != Null
if iterator even and minimum == Null
minimum = iterator
else if even and iterator < minimum
minimum = iterator
advance iterator
My five cents. I have also included a recursive function that finds the node with the maximum even value.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct nodo
{
int valore;
struct nodo *next;
};
int push_front( struct nodo **top, int valore )
{
struct nodo *nodo_nuovo = malloc( sizeof( struct nodo ) );
int success = nodo_nuovo != NULL;
if ( success )
{
nodo_nuovo->valore = valore;
nodo_nuovo->next = *top;
*top = nodo_nuovo;
}
return success;
}
FILE * display( struct nodo *top, FILE *fp )
{
for ( ; top != NULL; top = top->next )
{
fprintf( fp, "%d -> ", top->valore );
}
fputs( "null", fp );
return fp;
}
struct nodo * MinimoPariListaRic( struct nodo * top )
{
if ( !top )
{
return top;
}
else
{
struct nodo *minimo = MinimoPariListaRic( top->next );
if ( minimo == NULL )
{
minimo = top->valore % 2 == 0 ? top : minimo;
}
else if ( top->valore % 2 == 0 )
{
minimo = minimo->valore < top->valore ? minimo : top;
}
return minimo;
}
}
struct nodo * MassimoPariListaRic( struct nodo * top )
{
if ( !top )
{
return top;
}
else
{
struct nodo *massimo = MassimoPariListaRic( top->next );
if ( massimo == NULL )
{
massimo = top->valore % 2 == 0 ? top : massimo;
}
else if ( top->valore % 2 == 0 )
{
massimo = top->valore < massimo->valore ? massimo : top;
}
return massimo;
}
}
int main(void)
{
struct nodo *top = NULL;
enum { N = 10 };
srand( ( unsigned int )time( NULL ) );
for ( int i = 0; i < N; i++ )
{
push_front( &top, rand() % N );
}
fputc( '\n', display( top, stdout ) );
struct nodo *minimo = MinimoPariListaRic( top );
if ( minimo != NULL )
{
printf( "Minimo pari valore is %d\n", minimo->valore );
}
else
{
puts( "there is no minimo pari valore" );
}
struct nodo *massimo = MassimoPariListaRic( top );
if ( massimo != NULL )
{
printf( "Massimo pari valore is %d\n", massimo->valore );
}
else
{
puts( "there is no massimo pari valore" );
}
return 0;
}
The program output might look like
8 -> 9 -> 9 -> 9 -> 7 -> 9 -> 7 -> 3 -> 1 -> 2 -> null
Minimo pari valore is 2
Massimo pari valore is 8
As for your function definition then you need to check whether the pointer
minimo_p returned by the call
if(top->next)
minimo_p = MinimoPariListaRic(top->next);
is equal to NULL in the next if statement
if (top->valore % 2 == 0)
{
if(minimo_p->valore < top->valore) return minimo_p;
else return top;
}

Delete element from doubly linked list using recursive

I want to delete an element from doubly linked list, but i need to using recursion.
I write function but it doesn't work. Can someone tell me where did i a mistake?
int deleteNode(struct dll_node **front, int data){
if((*front) == NULL){
return 0;
}
if(data == (*front)->data){
int tmp = (*front)->data;
(*front)->next = (*front)->prev;
(*front)->prev = (*front)->next;
free(*front);
return tmp;
}
deleteNode((*front)->next, data);
}
there are several problems
you save data in tmp for nothing
you do not update rightly the list
your recursive call does not give right the first argument (must be deleteNode(&(*front)->next, data);, and in fact you must return it), note it is terminal so you can also use a loop
return is missing if the two tests are false
It can be :
int deleteNode(struct dll_node **front, int data){
if((*front) == NULL){
return 0;
}
if(data == (*front)->data){
struct dll_node * d = *front;
if (d->prev == NULL) {
if ((*front = d->next) != NULL)
(*front)->prev = NULL;
}
else if ((d->prev->next = d->next) != NULL)
d->next->prev = d->prev;
free(d);
return data;
}
return deleteNode(&(*front)->next, data);
}
Full code to check :
#include <stdio.h>
#include <stdlib.h>
struct dll_node {
int data;
struct dll_node * prev;
struct dll_node * next;
};
int deleteNode(struct dll_node **front, int data){
if((*front) == NULL){
return 0;
}
if(data == (*front)->data){
struct dll_node * d = *front;
if (d->prev == NULL) {
if ((*front = d->next) != NULL)
(*front)->prev = NULL;
}
else if ((d->prev->next = d->next) != NULL)
d->next->prev = d->prev;
free(d);
return data;
}
return deleteNode(&(*front)->next, data);
}
struct dll_node * mk(int d)
{
struct dll_node * r = malloc(sizeof(struct dll_node));
r->data = d;
r->prev = NULL;
r->next = NULL;
return r;
}
void pr(struct dll_node * l)
{
while (l != NULL) {
printf("%d", l->data);
if (l->prev)
printf(" prev:%d\n", l->prev->data);
else
putchar('\n');
l = l->next;
}
}
int main()
{
struct dll_node * head = mk(1);
struct dll_node * a = mk(2);
struct dll_node * b = mk(3);
head->next = a;
a->prev = head;
b->prev = a;
a->next = b;
pr(head);
puts("\ndel 3");
deleteNode(&head, 3);
pr(head);
puts("\ndel 1");
deleteNode(&head, 1);
pr(head);
puts("\ndel 2");
deleteNode(&head, 2);
pr(head);
}
Compilation and executions :
pi#raspberrypi:/tmp $ gcc -Wall l.c
pi#raspberrypi:/tmp $ ./a.out
1
2 prev:1
3 prev:2
del 3
1
2 prev:1
del 1
2
del 2
pi#raspberrypi:/tmp $ valgrind ./a.out
==8496== Memcheck, a memory error detector
==8496== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8496== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==8496== Command: ./a.out
==8496==
1
2 prev:1
3 prev:2
del 3
1
2 prev:1
del 1
2
del 2
==8496==
==8496== HEAP SUMMARY:
==8496== in use at exit: 0 bytes in 0 blocks
==8496== total heap usage: 4 allocs, 4 frees, 1,060 bytes allocated
==8496==
==8496== All heap blocks were freed -- no leaks are possible
==8496==
==8496== For lists of detected and suppressed errors, rerun with: -s
==8496== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
pi#raspberrypi:/tmp $

Delete all occurrences of a number in a linked list using recursion

I wanted to write a program that removes all occurrences of a number from a simple linked list using recursion, so I tried but I had problem: the program that I have written erases all the occurrences in the list but it does not delete the one that exists at the beginning (the occurrence that exists at the first node), here is the code in C:
typedef struct list {
int data;
struct list *next;
} list;
list *delete(int x, list *head) {
if (head->next == NULL)
return head;
list *newnode = delete(x, head->next);
if (newnode->data == x) {
head->next = head->next->next;
free(newnode);
}
return head;
}
I wish someone can help me to improve my algorithm, THANKS IN ADVANCE.
There are multiple problems in the code:
You dereference head without first checking if it is NULL. The function cannot handle empty lists.
You explicitly return the head node without testing its value if the list has a single element.
You only test the second element of the list after recursing on head->next. Hence the first element is never tested.
Here is a modified version that just tests the first node and recurses for the rest of the list:
list *delete(int x, list *head) {
if (head == NULL)
return head;
if (head->data == x) {
list *node = head;
head = head->next;
free(node);
return delete(x, head);
}
head->next = delete(x, head->next);
return head;
}
This code:
if(head->next == NULL)
return head;
explicitly makes the function return any 1-element list unchanged. That creates the problem you describe, so that makes no sense to have there.
I guess it should be possible to formulate the deletion of a list element recursively, although it certainly is not a common/typical/good way to do it.
This might work, not tested:
list * delete(list *head, int value)
{
if (head == NULL)
return NULL;
if (head->data == value)
{
list * tail = head->next;
free(head);
return delete(tail, value);
}
// List was not empty and did not start with the value,
// so set the tail of the list to the tail without the value.
head->next = delete(head->next, value);
return head;
}
without it manages to delete the one that exists at the beginning (the occurrence that exists at the first node),
this is because of these lines :
if(head->next == NULL)
return head;
when there is only one element you return without managing the fact it can contains the data to remove
You do not need to have a recursive definition of delete, and worst using non terminal recursion.
Can be also adding working functions to check the execution :
#include <stdio.h>
#include <stdlib.h>
typedef struct list {
int data;
struct list* next;
} list;
list* delete(int x, list* head)
{
list ** p = &head;
while (*p != NULL) {
if ((*p)->data == x) {
list * d = *p;
*p = (*p)->next;
free(d);
}
else
p = &(*p)->next;
}
return head;
}
void print(list * l)
{
if (l == NULL)
puts("<empty>");
else {
do {
printf("%d ", l->data);
l = l->next;
} while (l != NULL);
putchar('\n');
}
}
list * make(int data, list * next)
{
list * l = malloc(sizeof(list));
l->data = data;
l->next = next;
return l;
}
int main(int argc, char ** argv)
{
list * head = make(1, make(2, make(1, NULL)));
print(head);
head = delete(1, head);
print(head);
head = delete(2, head);
print(head);
return 0;
}
Compilation and execution:
/tmp % gcc -Wall l.c
/tmp % ./a.out
1 2 1
2
<empty>
/tmp %
Under valgrind :
/tmp % valgrind ./a.out ==14732== Memcheck, a memory error detector
==14732== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==14732== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==14732== Command: ./a.out
==14732==
1 2 1
2
<empty>
==14732==
==14732== HEAP SUMMARY:
==14732== in use at exit: 0 bytes in 0 blocks
==14732== total heap usage: 3 allocs, 3 frees, 48 bytes allocated
==14732==
==14732== All heap blocks were freed -- no leaks are possible
==14732==
==14732== For counts of detected and suppressed errors, rerun with: -v
==14732== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
/tmp %

Delete all the nodes from a list that respect a condition influenced by another list

I am studying the lists and I came across this exercise which asks me to do the following steps:
Define a function that, given two lists of integers L1 and L2, and an integer n>0, eliminate from the first list the nodes for which the sum of the contents of L1 and L2 in the corresponding position (with respect to the original positions) is a multiple of n. If L2 ends, consider only the content of L1 instead of the sum.
I tried to analyze the problem with a single list and in this case I had no problems, but in this specific case I couldn't figure out how to proceed.
my problem is that I can't understand how properly build the various cases (L1 must be always != NULL, so I have: L1 != NULL && L2 != NULL or L1 != NULL && L2 == NULL).
Can someone explain to me the procedure to be performed and where am I wrong?
This is my attempt:
struct data
{
int d;
struct data *next;
};
typedef struct data Nodo;
typedef Nodo *LIST;
void function(LIST *l1, LIST l2, int n)
{
LIST p, head_1, head_2;
while((*l1 != NULL && l2 != NULL)&&((*l1)->d + l2->d) % n == 0)
{
p = *l1;
*l1 = (*l1)->next;
free(p);
}
while((*l1 != NULL) && ((*l1)->d + l2->d) % n == 0)
{
p = *l1;
*l1 = (*l1)->next;
free(p);
}
if (*l1 != NULL)
{
head_1 = *l1;
head_2 = l2;
while(head_1->next != NULL)
{
if (((head_1->next->d + head_2->next->d) % n) == 0)
{
p = head_1->next;
head_1->next = head_1->next->next;
free(p);
}
else
{
head_1 = head_1->next;
head_2 = head_2->next;
}
}
}
}
Example:
L1: 4->4->11->3->4->8->7->NULL
L2: 5->1->5->1->5
OUTPUT(L1): 4->4->4->7->NULL
You have a problem of logic with the consecutive loops :
while((*l1 != NULL && l2 != NULL)&&((*l1)->d + l2->d) % n == 0) {
...
}
while((*l1 != NULL) && ((*l1)->d + l2->d) % n == 0){
...
}
if the sum of the elements are not a multiple of n you need to move to the next element, but you do not do
Out of that to hide a pointer with a typedef like you do with typedef Nodo *LIST; is dangerous and is a good way to introduce problem, I recommend you to never do that.
You can do that :
void removeIf(Nodo ** l1, Nodo * l2, int n)
{
while ((*l1 != NULL) && (l2 != NULL)) {
if ((((*l1)->d + l2->d) % n) == 0) {
/* cell must be removed */
Nodo * rm = *l1;
*l1 = (*l1)->next;
free(rm);
}
else {
/* cell not removed */
l1 = &(*l1)->next;
}
l2 = l2->next;
}
// case where l2 is shorter than l1
while (*l1 != NULL) {
if (((*l1)->d % n) == 0) {
/* cell must be removed */
Nodo * rm = *l1;
*l1 = (*l1)->next;
free(rm);
}
else {
/* cell not removed */
l1 = &(*l1)->next;
}
}
}
Making a full program for
L1: 4->4->11->3->4->8->7
L2: 5->1->5->1->5
N : 2
#include <stdio.h>
#include <stdlib.h>
struct data {
int d;
struct data *next;
};
typedef struct data Nodo;
void removeIf(Nodo ** l1, Nodo * l2, int n)
{
while ((*l1 != NULL) && (l2 != NULL)) {
if ((((*l1)->d + l2->d) % n) == 0) {
/* cell must be removed */
Nodo * rm = *l1;
*l1 = (*l1)->next;
free(rm);
}
else {
/* cell not removed */
l1 = &(*l1)->next;
}
l2 = l2->next;
}
// case where l2 is shorter than l1
while (*l1 != NULL) {
if (((*l1)->d % n) == 0) {
/* cell must be removed */
Nodo * rm = *l1;
*l1 = (*l1)->next;
free(rm);
}
else {
/* cell not removed */
l1 = &(*l1)->next;
}
}
}
Nodo * make(int v, Nodo * n)
{
Nodo * r = malloc(sizeof(Nodo));
r->d = v;
r->next = n;
return r;
}
void del(Nodo ** pl)
{
while (*pl != NULL) {
Nodo * n = *pl;
*pl = (*pl)->next;
free(n);
}
}
int main()
{
Nodo * l1 = make(4, make(4, make(11, make(3, make(4, make(8, make(7, NULL)))))));
Nodo * l2 = make(5, make(1, make(5, make(1, make(5, NULL)))));
removeIf(&l1, l2, 2);
/* show result */
for (Nodo * l = l1; l != NULL; l = l->next)
printf("%d ", l->d);
putchar('\n');
/* free resources */
del(&l1);
del(&l2);
return 0;
}
Compilation and execution :
pi#raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra ll.c
pi#raspberrypi:/tmp $ ./a.out
4 4 4 7
pi#raspberrypi:/tmp $
Execution under valgrind :
pi#raspberrypi:/tmp $ valgrind ./a.out
==3758== Memcheck, a memory error detector
==3758== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3758== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==3758== Command: ./a.out
==3758==
4 4 4 7
==3758==
==3758== HEAP SUMMARY:
==3758== in use at exit: 0 bytes in 0 blocks
==3758== total heap usage: 13 allocs, 13 frees, 1,120 bytes allocated
==3758==
==3758== All heap blocks were freed -- no leaks are possible
==3758==
==3758== For counts of detected and suppressed errors, rerun with: -v
==3758== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
pi#raspberrypi:/tmp $

Issue when creating linked list and add nodes to it [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I understand this question has been explained a lot but in fact I am desperate from my code. I want to create a linked list that create 5 new nodes and add them at the end of list one by one:
typedef struct msg *M;
struct msg{
double data;
M next;
};
void create_msg();
void add();
void main(){
srand(0);
M list_of_msg = NULL;
for( int i = 0; i < 5; i++){
create_msg(list_of_msg);
add(list_of_msg , rand()%15);
}
}
void create_msg(M head){
M m;
m = (M)malloc(sizeof(struct msg));
if(head == NULL)
{
head = m;
head->next = NULL;
}
else
{
m->next= head;
head = m;
}
return(m);
}
void add(M head, double d){
M m, last;
m = (M)malloc(sizeof(struct msg));
last = head;
m->data = d;
m->next = NULL;
if (head == NULL)
{
head = m;
}
else
{
while (last->next != NULL)
{
last = last->next;
}
last->next = m;
}
}
The program does not work and I don't know where is the problem even though I checked line by line. Any hint is appreciated.
issues
missing stdlib include for malloc prototype
function add is coded to handle null message parameters, create_msg is not necessary ( and duplicates the code in add )
add and create_msg prototypes inconsistent with function definitions below
void main is not one of the standard main prototypes
create_msg declared as void, but returns a value
function add ( and create_msg ) attempt to modify their M input parameter ( which is just a local copy )
no error checking after malloc
no need to cast void * return of malloc
declaring integer in for loop header reduces portability
Message memory is leaking ( no way to free the memory )
you have no way to print the link list to know if it worked..
code
#include <stdio.h>
#include <stdlib.h>
typedef struct msg *M;
struct msg{
double data;
M next;
};
#define create_msg(M)
void add(M *head, double d);
void print_messages(M head);
void free_messages(M head);
int main(void){
srand(0);
M list_of_msg = NULL;
int i;
create_msg(list_of_msg);
for( i = 0; i < 5; i++){
/* create_msg function was redundant and removed to a noop */
/* create_msg(list_of_msg);*/
add(&list_of_msg , rand()%15);
}
print_messages(list_of_msg);
free_messages(list_of_msg);
return 0;
}
void add(M *head, double d){
M m, last;
m = malloc(sizeof(struct msg));
if(!m)
{
/* consider making add return int
* this way can throw an error code and check for it from client */
return ;
}
last = *head;
m->data = d;
m->next = NULL;
if (*head == NULL)
{
*head = m;
}
else
{
while (last->next != NULL)
{
last = last->next;
}
last->next = m;
}
}
void print_messages(M head)
{
M cursor = head;
while(cursor)
{
printf("%lf ->\n", cursor->data);
cursor = cursor->next;
}
}
void free_messages(M head)
{
M cursor, next;
cursor = head;
while(cursor)
{
next = cursor->next;
free(cursor);
cursor = next;
}
}
output
$ gcc -g test.c -o test
$ valgrind ./test
==1121== Memcheck, a memory error detector
==1121== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==1121== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==1121== Command: ./test
==1121==
13.000000 ->
1.000000 ->
12.000000 ->
10.000000 ->
8.000000 ->
==1121==
==1121== HEAP SUMMARY:
==1121== in use at exit: 0 bytes in 0 blocks
==1121== total heap usage: 5 allocs, 5 frees, 80 bytes allocated
==1121==
==1121== All heap blocks were freed -- no leaks are possible
==1121==
==1121== For counts of detected and suppressed errors, rerun with: -v
==1121== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
reference
c main return codes
valgrind quickstart
casting malloc

Resources