创建链接列表并向其添加节点时出现问题

时间:2015-11-14 23:05:23

标签: c

我理解这个问题已经解释了很多,但实际上我对我的代码感到绝望。我想创建一个链接列表,创建5个新节点,并逐个添加到列表末尾:

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

该程序不起作用,即使我逐行检查,我也不知道问题出在哪里。任何提示都表示赞赏。

1 个答案:

答案 0 :(得分:1)

<强>问题

  
      
  • 缺少stdlib include for malloc prototype
  •   
  • 函数add被编码为处理空消息参数,create_msg不是必需的(并且重复添加代码)
  •   
  • add和create_msg原型与下面的函数定义不一致
  •   
  • void main不是标准主要原型之一
  •   
  • create_msg声明为void,但返回值
  •   
  • function add(和create_msg)尝试修改其M输入参数(只是本地副本)
  •   
  • 在malloc之后没有错误检查
  •   
  • 无需投射void *返回malloc
  •   
  • 声明for循环标头中的整数会降低可移植性
  •   
  • 消息内存泄漏(无法释放内存)
  •   
  • 您无法打印链接列表以了解其是否有效..
  •   

<强>码

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

<强>输出

$ 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)

<强>参考