新闻中心

EEPW首页 > 嵌入式系统 > 牛人业话 > C语言的那些小秘密之链表(二)

C语言的那些小秘密之链表(二)

作者:时间:2015-04-11来源:网络收藏

  虽然两个指针变量存放在不同的单元,但是它们都指向同一个存储单元,所以在释放的时候只能释放一次,如果释放两次就会出错。注意切不可同时使用free(pointer_1);和 free(pointer_2);,否则将会出现内存错误。对出错原因不懂的可以参考我前面的文章《的那些小秘密之指针》。这个代码和我们双的最大区别是它只能使用free()函数进行一次释放,而我们双中看似使用了两次,但实则一次而已。原因就在于我们在对头结点分配空间的时候分配的是存放data指针变量的存储空间(注意:所有的指针变量在分配的时候均分配4字节大小的存储空间,如果有什么疑惑可以参考我之前写的《的那些小秘密之指针》)。所以释放的时候也是释放的存放指针变量data的存储空间,并没有释放掉指针变量data所指向的存储空间。所以在释放data指向的存储空间时,我们只需要在main()函数中对stu[i]所指向的存储空间使用free()函数即可,因为data和它指向的是同一个存储空间。

本文引用地址:http://www.eepw.com.cn/article/272382.htm

  接下来我们来添加一个在头结点添加结点的模块。

  #include

  #include

  typedef enum _DListReturn

  {

  DLIST_RETURN_OK,

  DLIST_RETURN_FAIL

  }DListReturn;

  typedef struct _DStu

  {

  int score;

  }DStu;

  typedef struct _DListNode

  {

  struct _DListNode* prev;

  struct _DListNode* next;

  DStu* data;

  }DListNode;

  typedef struct _DList

  {

  DListNode* head;

  }DList;

  typedef DListReturn (*DListPrintFunction)(void* data);

  DListNode* dlist_node_create(void* data)

  {

  DListNode* node;

  if((node = (DListNode*) malloc(sizeof(DListNode)))==NULL)

  {

  printf("分配空间失败!");

  exit(0);

  }

  if(node != NULL)

  {

  node->prev = NULL;

  node->next = NULL;

  node->data =(DStu*)data;

  }

  return node;

  }

  DList* dlist_head_create(void)

  {

  DList* thiz;

  if((thiz = (DList*)malloc(sizeof(DList)))==NULL)

  {

  printf("分配空间失败!");

  exit(0);

  }

  if(thiz != NULL)

  {

  thiz->head = NULL;

  }

  return thiz;

  }

  DListReturn dlist_append(DList* thiz, void* data)

  {

  DListNode* node = NULL;

  DListNode* cursor = NULL;

  if((node = dlist_node_create(data)) == NULL)

  {

  return DLIST_RETURN_FAIL;

  }

  if(thiz->head == NULL)

  {

  thiz->head = node;

  return DLIST_RETURN_OK;

  }

  cursor = thiz->head;

  while(cursor != NULL && cursor->next != NULL)

  {

  cursor = cursor->next;

  }

  cursor->next = node;

  node->prev = cursor;

  return DLIST_RETURN_OK;

  }

  DListReturn dlist_prepend(DList* thiz, void* data)

  {

  DListNode* node = NULL;

  DListNode* cursor = NULL;

  if((node = dlist_node_create(data)) == NULL)

  {

  return DLIST_RETURN_FAIL;

  }

  if(thiz->head == NULL)

  {

  thiz->head = node;

  return DLIST_RETURN_OK;

  }

  cursor = thiz->head;

  if(thiz->head == cursor)

  thiz->head = node;

  node->next = cursor;

  cursor->prev = node;

  return DLIST_RETURN_OK;

  }

  DListReturn dlist_print(DList* thiz, DListPrintFunction print)

  {

  DListNode* iter = thiz->head;

  while(iter != NULL)

  {

  print(iter->data);

  iter = iter->next;

  }

  printf("\n");

  return DLIST_RETURN_OK;

  }

  DListReturn print_int(void* data)

  {

  DStu* ss=(DStu*)data;

  printf("%d\t ", ss->score);

  return DLIST_RETURN_OK;

  }

  DListReturn dlist_node_destroy(DListNode* node)

  {

  if(node != NULL)

  {

  node->next = NULL;

  node->prev = NULL;

  free(node);

  }

  return DLIST_RETURN_OK;

  }

  DListReturn dlist_destroy(DList* thiz)

  {

  DListNode* iter = thiz->head;

  DListNode* next = NULL;

  while(iter != NULL)

  {

  next = iter->next;

  dlist_node_destroy(iter);

  iter = next;

  }

  thiz->head = NULL;

  free(thiz);

  return DLIST_RETURN_OK;

  }

  int main(int argc, char* argv[])

  {

  int i = 0;

  DList* dlist = dlist_head_create();

  for(i = 0; i < 7; i++)

  {

  DStu* stu =(DStu*) malloc(sizeof(DStu));

  stu->score = i;

  dlist_append(dlist, (void*)stu);

  }

  for(i = 0; i < 7; i++)

  {

  DStu* stu =(DStu*) malloc(sizeof(DStu));

  stu->score = i;

  dlist_prepend(dlist, (void*)stu);

  }

  dlist_print(dlist, print_int);

  dlist_destroy(dlist);

  return 0;

  }

  我们在上一段代码添加了红色部分代码后,使得其在已经生成的双的头结点处添加结点,运行结果如下:

  

 

  6 5 4 3 2 1 0 0 1 2

  3 4 5 6

  Press any key to continue

  可以看出结果与我们的要求完全符合。如果你认真分析了代码的话你就会发现,我们的两种添加方式中有公共代码出现,那就说明我们的代码可以继续改进,把公共代码放到一个函数中,读者可以另外编写一个函数来实现,使得我们编写的代码得到充分的利用。

  篇幅似乎有些过长了,接下来我就不再一一讲解了,我在这里只是想起一个引路的作用,读者完全可以在此基础之上继续编写双链表其余部分的功能,其他的功能模块读者可以在此基础上一一添加上去,到下一篇的时候我们将走进linux内核链表,继续链表之旅的最后一站。由于本人水平有限,博客中的不妥或错误之处在所难免,殷切希望读者批评指正。同时也欢迎读者共同探讨相关的内容,如果乐意交流的话请留下你宝贵的意见。


上一页 1 2 3 下一页

关键词: C语言 链表

评论


相关推荐

技术专区

关闭