一个链表。。可耻的漏了

shiweifu 2010-05-20 11:58:35
看到《系统程序员成长计划》这本书里面讲了通用链表的实现,豁然开朗,(好像C语言接口与实现中也有实现)
随手写了个,插字符串、整形、浮点均可,也都能正常输出。写完之后,拿VS测试一下,发现字符串部分漏了……

先贴完整源码:

#define __WIN

//VS中的内存检测
#ifdef __WIN

#define _CRTDBG_MAP_ALLOC
#include<stdlib.h>
#include<crtdbg.h>

#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#define __DEBUG__

typedef void* (*list_func)(void* x);

typedef enum _node_type
{
INT,
STRING,
DOUBLE
} node_type;

typedef struct _node node;
struct _node
{
node *next;
void *v;
size_t len;
node_type t;
};

//创建节点
node *creat_node(size_t n,node_type t)
{
node *tmp;
tmp = (node*)malloc(sizeof(node));
tmp->next = NULL;
tmp->len = n;
tmp->v = malloc(tmp->len);
tmp->t = t;
memset(tmp->v,0,tmp->len);
return tmp;
}

//添加节点
node *list_add(node *parent,void* v,node_type t)
{
node *tmp;
node *cur;
unsigned char len = 0;

//通过节点类型,判断大小
switch(t)
{

case STRING:
len = strlen((char*)v) + 1;
break;

case INT:
len = sizeof(int);
break;
case DOUBLE:
len = sizeof(double);
break;
}

//创建节点,给出所占内存大小
tmp = creat_node(len,t);

//tmp->v = v;
//这里不能用memset函数,它是按字节对指针进行改变的,只会复制过去第一个字节,该选用memcpy
// memset(tmp->v,v,sizeof(v));
memcpy(tmp->v,v,len);
if(parent != NULL)
{
cur = parent;
while(cur->next != NULL) cur = cur->next;
cur->next = tmp;
}
return tmp;
}

node *list_remove(node *parent,int v)
{
return 0;
}

void output(node *n)
{
switch(n->t)
{
case INT:
printf("%d\r\n",*(int*)(n->v));
break;
case STRING:
printf("%s\r\n",(char*)n->v);
break;
case DOUBLE:
printf("%.2f\r\n",*(double*)n->v);
break;
}
}

//按照书上写的,将链表中的字符转换为大写
void set_member_to_upper(node *n)
{

int i;
char *p;
if(n->t == STRING)
{
p = (char*)n->v;
for(i = 0; p[i] != '\0'; p[i] = toupper(p[i]), i++);
}
}

//销毁链表
node *list_destroy(node *parent)
{
node *tmp = NULL;
node *cur = parent;
#ifdef __DEBUG__
puts("kill");
#endif
while(cur != NULL)
{
tmp = cur->next;
#ifdef __DEBUG__
//puts("kill one");
//printf("%s\r\n",(char*)cur->v);
//output(cur);
#endif
free(cur->v);
free(cur);
cur = tmp;
}
return 0;
}

//遍历链表中的数据项
int list_foreach(node *parent,list_func lf)
{
node *cur;
for(cur = parent; cur != NULL; lf(cur),cur = cur->next);
return 0;
}

int main()
{

int n = 50;
double x;
char *pstr = (char*)malloc(10);

node *list = list_add(NULL,strdup("a"),STRING);
list_add(list,strdup("abcdef"),STRING);
list_add(list,strdup("aadsfdfg"),STRING);

/*list_add(list,&n,INT);
n = 60;
list_add(list,&n,INT);
n = 70;
list_add(list,&n,INT);
n = 500;
list_add(list,&n,INT);
x = 9.00009;
list_add(list,&x,DOUBLE);*/


//for(i = 1; i < 5;list_add(list,i * 2),i++);
// list_foreach(list,output);
//list_foreach(list,set_member_to_upper);
//list_foreach(list,output);
free(pstr);
list_destroy(list);
system("pause");

_CrtDumpMemoryLeaks();


return 0;
}



再来漏的地方:
d:\我的文档\visual studio 2008\projects\linklist\main.c(167) : {61} normal block at 0x003929E8, 9 bytes long.
Data: <aadsfdfg > 61 61 64 73 66 64 66 67 00
d:\我的文档\visual studio 2008\projects\linklist\main.c(166) : {58} normal block at 0x00395FD8, 7 bytes long.
Data: <abcdef > 61 62 63 64 65 66 00
d:\我的文档\visual studio 2008\projects\linklist\main.c(165) : {55} normal block at 0x00395F08, 2 bytes long.
Data: <a > 61 00
Object dump complete.

只有字符串会漏,整形和浮点都不会漏,跟了下,觉得释放也没问题啊,求教~
...全文
97 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
shiweifu 2010-05-20
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 logiciel 的回复:]

泄露的内存是strdup自动分配的内存.因此在creat_node中,对于字符串不要执行以下语句:

tmp->v = malloc(tmp->len);
memset(tmp->v,0,tmp->len);

在调用creat_node后不能用memcpy(tmp->v,v,len),要改用tmp->v = v.
[/Quote]

学习了~
logiciel 2010-05-20
  • 打赏
  • 举报
回复
泄露的内存是strdup自动分配的内存.因此在creat_node中,对于字符串不要执行以下语句:

tmp->v = malloc(tmp->len);
memset(tmp->v,0,tmp->len);

在调用creat_node后不能用memcpy(tmp->v,v,len),要改用tmp->v = v.
AlanBruce 2010-05-20
  • 打赏
  • 举报
回复
UP


Up

dongnanfanlin 2010-05-20
  • 打赏
  • 举报
回复
我没检测泄漏的工具,不知道是不是有问题

不过,看代码的
memcpy(tmp->v,v,len);

这一句最好改为 memcpy(tmp->v,v,len-1),

因为你 len 设置的是长度加 1,目的就是为了最后一个字符填 '\0'。同时 creat_node 里面把 len 个字节全部清空了。

所以你内存拷贝的时候只要拷贝 len-1 个字节就可以了。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧