首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通用链表代码C

通用链表代码C
EN

Code Review用户
提问于 2017-08-20 08:58:14
回答 2查看 703关注 0票数 2

我已经创建了以下代码:在C中实现链接列表。

为了测试它,我创建了一个标签结构,其中包含一个stringint变量。

在上传到这里之前,代码是很好的注释和测试。

我想听听你对此的看法,我也不确定freemalloc是否运行良好(我使用了DrMemory,它没有出现错误,但是内存是一个“漏”的东西(lol))。

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
#include <stdlib.h>


/*label */
/*The label is managed by lnode, which contains the address-string(8-bits)
  and the label-name. */
  typedef struct label{
            int   address;             /* The address number.                      */
            char* name;                /* The name of the label.                   */
  }label;

/*Label implementation*/
/*Create label object*/
  label* createLabel(int address, char* name)
  {
      int len;
      label* newlabel;
      if(NULL == name){
         return NULL;
      }
      len = strlen(name)+1;
      newlabel = (label*)malloc(sizeof(label));
      if(NULL == (newlabel->name = (char*)malloc(sizeof(char)*len))){
        return NULL;
      }
    /*copy name to new-label name*/
      strcpy(newlabel->name, name);
    /*set address in newlabel*/
      newlabel->address = address;
      return(newlabel);
  }
/*delete label object*/
  void deleteLabel(void* ob ){
       label *lbl;
       if(NULL == ob){
          return;
       }
       lbl = (label*)ob;
     /*delete the name*/
       free(lbl->name);
     /*delete the Label object*/
       free(lbl);
  }

/*Print Label-objects --> for Testing*/
/*Allocate a string and fill with label data*/
  void printLabel(void* ob){
       label* obl= (label*)ob;
       printf("%s%d,  label: %-10s, ","address: ",obl->address,obl->name);
  }






/*gnode*/
/*generic-node struct to be used in a generic list*/
  struct gnode{
       void *value;        /*pointer to generic-node */
       struct gnode* next; /*pointer to next node    */
  }typedef gnode;


/*createGnode*/
/*create a gnode to be added to a generic-list*/
  gnode* createGnode( void* value, gnode* next){
      gnode* newnode=NULL;
      if(NULL == value){
         return NULL;
      }
      if (NULL == (newnode = (gnode*)malloc(sizeof(gnode)))) {
        return NULL;
      }
    /*add the value*/
      newnode->value = value;
    /*set next value to be NULL --> All added gnode are
      added at the end of the list and become the last node */
      newnode->next = next;
      return(newnode);
  }



/*freeGnode*/
/*free the allocated gnode, using a function to delete the pointed value  */
  void freeGnode(gnode* nodetodelete,  void (*deletefunc)( void*)){
     if(NULL == nodetodelete){
        return;
     }
   /*delete the value, pointed by void* value */
     deletefunc(nodetodelete->value);
   /*free the allocated gnode*/
     free(nodetodelete);
  }


/*insertGnode --> insert gnode to list*/
  int insertGnode(gnode** glist, gnode* newnode)
  {
      gnode* curr; /*pointer to current node in list*/
      if(NULL == newnode){
         return -1; /*no item to insert*/
      }
    /*Empty list*/
      else if(NULL == *glist){
              *glist = newnode;
              return 1;
      }
    /*add newnode in last place in list*/
    /*Get to last node*/
      for( curr = *glist; curr->next != NULL; curr = curr->next);
    /*Add the newnode as last node*/
      curr->next = newnode;
    /*return Success*/
      return 1;
  }


/*deleteGenericList*/
/*Parse each generic-node and delete */
  void deleteGenericList(gnode* glist, void (*deleteValue)(void*))
  {
     gnode* curr=NULL;
     gnode* next;
     if(NULL == glist){
        return;
     }
   /*Delete each generic-node*/
     for(curr = glist; curr != NULL; ){
         next = curr->next;
         deleteValue(curr->value); /*free the value objext     */
         free(curr);               /*free current generic-node */
         curr = next;
     }
   /*Set glist to point at NULL*/
     glist = NULL;
  }/*End deleteGenericList*/


/*writeGlist --> write Gnode to an open-file*/
  void writeGenericList(FILE* fp, gnode* glist, void (*writeValue)(FILE*, void*))
  {
      gnode* curr=NULL; /*curr node in the generic-list*/
    /*check that all arguments are present*/
      if( (NULL == fp)||(NULL==glist)||(NULL==writeValue) ){
           return;
      }
    /*use the writeValue function to write the gnode into the file*/
      for(curr = glist; curr != NULL; curr=curr->next){
          writeValue(fp, curr->value);
      }
  }/*End writeGenericList*/


/*For testing...*/
  void printGlist(gnode* glist, void (*printValue)(void*)){
      gnode *curr;
      if(NULL == glist){
         return;
      }
      for (curr = glist; curr != NULL; curr = curr->next){
           printValue(curr->value);
      }
  }


  void printGlistOLD(gnode* glist, void (*printValue)(void*)){
      gnode *curr;
      if(NULL == glist){
         return;
      }
      printf("%-20s\n", "GenericList: top-To-Bottom");
      for (curr = glist; curr != NULL; curr = curr->next){
           printValue(curr->value);
      }
  }

  int main(int argc, char const *argv[])
  {
    printf("start\n");
    label *label1 = createLabel(100,"hello world");
    label *label2 = createLabel(101,"a");
    label *label3 = createLabel(102,"b");
    label *label4 = createLabel(100,"c");
    label *label5 = createLabel(103,"d");
    label *label6 = createLabel(102,"e");


    gnode* g1 = createGnode(label1,NULL);
    gnode* g2 = createGnode(label2,NULL);
    gnode* g3 = createGnode(label3,NULL);
    gnode* g4 = createGnode(label4,NULL);
    gnode* g6 = createGnode(label6,NULL);
    gnode* g5 = createGnode(label5,g6);

    printf("%d\n",insertGnode(&g1,g2));
    printf("%d\n",insertGnode(&g1,g3));
    printf("%d\n",insertGnode(&g1,g4));
    printf("%d\n",insertGnode(&g1,g5));

    printGlistOLD(g1,printLabel);

    deleteGenericList(g1,deleteLabel);
    return 0;
  }

谢谢!

EN

回答 2

Code Review用户

发布于 2017-08-21 06:48:45

  • 正如我在上一篇评论中提到的,不要在注释中重复代码。我们非常理解strcpy(newlabel->name, name);的目的。
  • 正如我在上一次检讨中所说,不要投马洛。
  • insertGnode不插入,而是添加到列表中。考虑改名。您似乎并不担心列表中节点的顺序。考虑对新节点进行前缀,如int add_gnode( gnode* * glist,gnode* newnode) { if (newnode == NULL) {rever-1;}newnode>next= *glist;*glist= newnode;返回1;}这种方法有两个好处:
    • 它不是为了找到尾巴而遍历整个列表,而且
    • 这不是特殊情况下的空名单。

  • printGlist应该用适当的参数调用writeGenericList
  • 您似乎在努力实现面向对象的方法。考虑让genericList结构以deletefuncwriteValue等为成员。
票数 1
EN

Code Review用户

发布于 2017-08-21 09:16:03

  • 当您不应该使用C语言时,您一直使用void *:newlabel =( label* )malloc(sizeof(标签));应是: newlabel =malloc(sizeof(标签));以及void printLabel( void ){ label* obl = (label*)ob;应该是:void(void* ob) {标签* obl = ob;
  • create_label中有一个潜在的内存泄漏: newlabel = malloc (sizeof(标签));//不要强制转换malloc if (空== (新标签->name=malloc(sizeof(Char)*len)){返回空;//泄漏先前分配的标签}
  • 对于node管理,名称是不一致的:当注释说最后一个时,createGnode插入节点位于第一个位置,而insertGnode将它添加到最后一个位置。
  • freeGnode无条件地释放节点及其内容,如果您删除列表中的节点,则=>中的任何链接都可能断开,至少在注释中显示不能从列表中删除节点。
  • deleteGenericList(gnode* glist, void(*deleteValue)(void*))中,最后一条指令(glist = NULL;)是无操作的,因为它只设置将在下一行超出作用域的函数中的局部值。
  • 您应该考虑添加一个函数来从列表中删除节点。
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/173452

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档