-1

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.

Mike
  • 368
  • 3
  • 15

1 Answers1

1

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

Community
  • 1
  • 1
amdixon
  • 3,703
  • 8
  • 23
  • 33