Chinaunix
标题:
有一个内存泄漏问题
[打印本页]
作者:
BuTa丶潇
时间:
2013-07-25 11:02
标题:
有一个内存泄漏问题
本帖最后由 BuTa丶潇 于 2013-07-25 12:57 编辑
不好意思 我有一个问题,貌似是内存泄漏..
我查了几遍,都没找到问题原因..
代码内容大致:
就是我插入几个元素 然后放到链表里..
最后释放的时候
释放完 再遍历 还是有数据..
代码如下,大概就几十行,可以直接运行看到问题..
麻烦谁帮忙看下哪里出的问题吧..谢谢谢谢...
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX_ADDR_LEN 128
#define MAX_LINE_LEN 512
#define pError(x) printf("%s\n",x);
#define tfree(x) { if ( x ) { free(x); x = NULL; } }
//链表结构
typedef struct vCard_unique_name_addr
{
char name[MAX_LINE_LEN];
char addr[MAX_ADDR_LEN];
struct vCard_unique_name_addr* pNext;
}vCard_uni_nam_adr;
//释放
static void uni_name_adr_tmp_listfree(vCard_uni_nam_adr * puni_name_adr)
{
vCard_uni_nam_adr * pTmpuni_nam_adr_pos = NULL;
vCard_uni_nam_adr * pTmpuni_nam_adr_next = NULL;
if(NULL == puni_name_adr)
{
return ;
}
pTmpuni_nam_adr_pos = puni_name_adr;
for(;pTmpuni_nam_adr_pos != NULL;pTmpuni_nam_adr_pos = pTmpuni_nam_adr_next){
pTmpuni_nam_adr_next = pTmpuni_nam_adr_pos->pNext;
tfree(pTmpuni_nam_adr_pos);
}
return;
}
//如果有重复的 那么就忽略,即return 1;
//如果没重复的 那么就追加到链表的最后.
static int check_distinct_nam_adr(vCard_uni_nam_adr ** pTmpuni_nam_adr_head , const char *name, const char * addr){
vCard_uni_nam_adr * pTmpuni_nam_adr_next = NULL;
vCard_uni_nam_adr * pTmpuni_nam_adr_pos = NULL;
pTmpuni_nam_adr_pos = *pTmpuni_nam_adr_head ;
while(pTmpuni_nam_adr_pos != NULL){
if( strcmp(pTmpuni_nam_adr_pos->name,name)==0 && strcmp(pTmpuni_nam_adr_pos->addr,addr)==0 ){
return 1;
}
pTmpuni_nam_adr_next = pTmpuni_nam_adr_pos;
pTmpuni_nam_adr_pos = pTmpuni_nam_adr_pos->pNext;
}
pTmpuni_nam_adr_pos = (vCard_uni_nam_adr*)malloc(sizeof(vCard_uni_nam_adr));
if(NULL == pTmpuni_nam_adr_pos)
{
pError("Get memory failure while distinct vcard info");
uni_name_adr_tmp_listfree(*pTmpuni_nam_adr_head);
}
else
{
memset(pTmpuni_nam_adr_pos,0,sizeof(vCard_uni_nam_adr));
pTmpuni_nam_adr_pos->pNext = NULL;
strcpy(pTmpuni_nam_adr_pos->name,name ? name : "null");
strcpy(pTmpuni_nam_adr_pos->addr,addr ? addr : "null");
if(NULL == *pTmpuni_nam_adr_head){
*pTmpuni_nam_adr_head = pTmpuni_nam_adr_pos;
}
else{
pTmpuni_nam_adr_next->pNext = pTmpuni_nam_adr_pos;
}
}
return 0;
}
int main(void){
vCard_uni_nam_adr * pTmpuni_nam_adr_head = NULL;
check_distinct_nam_adr(&pTmpuni_nam_adr_head,"nihao","188888");
check_distinct_nam_adr(&pTmpuni_nam_adr_head,"hello","55555");
check_distinct_nam_adr(&pTmpuni_nam_adr_head,"nihao","188888");
check_distinct_nam_adr(&pTmpuni_nam_adr_head,"hello","188888");
check_distinct_nam_adr(&pTmpuni_nam_adr_head,"qqqq","000000");
vCard_uni_nam_adr * pp = pTmpuni_nam_adr_head;
while(pp != NULL){
// sleep(1);
printf("name:%s,addr:%s\n",pp->name,pp->addr);
pp = pp->pNext;
}
printf("==================\n");
uni_name_adr_tmp_listfree(pTmpuni_nam_adr_head);
vCard_uni_nam_adr *xp = pTmpuni_nam_adr_head;
while(xp != NULL){
// sleep(1);
printf("name:%s,addr:%s\n",xp->name,xp->addr);
xp = xp->pNext;
}
}
作者:
pmerofc
时间:
2013-07-25 11:12
提示:
作者被禁止或删除 内容自动屏蔽
作者:
lxyscls
时间:
2013-07-25 11:19
valgrind跑一次
作者:
BuTa丶潇
时间:
2013-07-25 11:29
回复
2#
pmerofc
这个是我当时想测试下 释放完毕后,他是否还存在数据...
如果正常的话 他应该不会进入到这里..
这个就是我不太理解的地方..我释放完毕了怎么还有数据..
**内存泄漏的问题呢..求赐教..谢谢谢谢...
作者:
pmerofc
时间:
2013-07-25 11:48
提示:
作者被禁止或删除 内容自动屏蔽
作者:
dxyf1524
时间:
2013-07-25 11:53
我估计你是释放函数的参数传递出了问题,函数传值不传址,释放后要将指针置为空
作者:
pmerofc
时间:
2013-07-25 12:33
提示:
作者被禁止或删除 内容自动屏蔽
作者:
BuTa丶潇
时间:
2013-07-25 13:24
回复
7#
pmerofc
嗯 你的意思是我访问了已经释放的内容,所以导致出错是吗..
我在释放的时候 释放完毕后,设置指针为NULL,
之后是因为想看下是否释放完全,所以在外面访问的时候,先判断是否为NULL,然后才访问的..正常的话不是不应该进入if条件的吗..
不好意思 有点迷糊...能不能麻烦再详细讲解一下 谢谢谢谢..
作者:
pix77
时间:
2013-07-25 13:24
lxyscls 发表于 2013-07-25 11:19
valgrind跑一次
+1
作者:
BuTa丶潇
时间:
2013-07-25 13:34
回复
3#
lxyscls
谢谢,我接触c没多久 , 还没用过这个东西..我去网上看下..
作者:
pmerofc
时间:
2013-07-25 13:39
提示:
作者被禁止或删除 内容自动屏蔽
作者:
BuTa丶潇
时间:
2013-07-25 14:37
回复
11#
pmerofc
嗯 ,第一次的代码确实有访问已经释放的的内容,当时是想测试下为何已经释放并置null了 却还存在数据.. 现在看来 无意义了,所以改了下..
我不太清楚你说的风格概念..可能命名不太好,还是注释太少...这些我以后注意..
我先把逻辑再理一遍,然后看下**问题吧...要不以这个思路走下去,我感觉风格还是老样子..谢谢你哈..
作者:
pmerofc
时间:
2013-07-25 15:37
提示:
作者被禁止或删除 内容自动屏蔽
作者:
j3kljs02398j
时间:
2013-07-25 17:46
lxyscls 发表于 2013-07-25 11:19
valgrind跑一次
+1
三楼已经告诉你了很好的解决方式
作者:
dxyf1524
时间:
2013-07-26 08:48
uni_name_adr_tmp_listfree(pTmpuni_nam_adr_head);
vCard_uni_nam_adr *xp = pTmpuni_nam_adr_head;
问题就是出在这里,uni_name_adr_tmp_listfree(pTmpuni_nam_adr_head);返回后“pTmpuni_nam_adr_head != NULL”
按照你的用法,要么用二级指针,要么释放完将一级指针置为空
作者:
BuTa丶潇
时间:
2013-07-26 10:35
回复
15#
dxyf1524
谢谢你..
我重新修改了下代码,
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX_ADDR_LEN 128
#define MAX_LINE_LEN 512
#define pError(x) printf("%s\n",x);
#define tfree(x) { if ( x ) { free(x); x = NULL; } }
typedef struct vCard_unique_name_addr
{
char name[MAX_LINE_LEN];
char addr[MAX_ADDR_LEN];
struct vCard_unique_name_addr* pNext;
}vCard_uni_nam_adr;
static void uni_name_adr_tmp_listfree(vCard_uni_nam_adr ** puni_name_adr)
{
vCard_uni_nam_adr * pTmpuni_nam_adr_pos = NULL;
vCard_uni_nam_adr * pTmpuni_nam_adr_next = NULL;
if(NULL == *puni_name_adr)
{
return ;
}
pTmpuni_nam_adr_pos = *puni_name_adr;
for(;pTmpuni_nam_adr_pos != NULL;pTmpuni_nam_adr_pos = pTmpuni_nam_adr_next){
pTmpuni_nam_adr_next = pTmpuni_nam_adr_pos->pNext;
tfree(pTmpuni_nam_adr_pos);
}
*puni_name_adr =NULL;
return;
}
static int check_distinct_nam_adr(vCard_uni_nam_adr ** pTmpuni_nam_adr_head , const char *name, const char * addr){
vCard_uni_nam_adr * pTmpuni_nam_adr_next = NULL;
vCard_uni_nam_adr * pTmpuni_nam_adr_pos = NULL;
pTmpuni_nam_adr_pos = *pTmpuni_nam_adr_head ;
while(pTmpuni_nam_adr_pos != NULL){
if( strcmp(pTmpuni_nam_adr_pos->name,name)==0 && strcmp(pTmpuni_nam_adr_pos->addr,addr)==0 ){
return 1;
}
pTmpuni_nam_adr_next = pTmpuni_nam_adr_pos;
pTmpuni_nam_adr_pos = pTmpuni_nam_adr_pos->pNext;
}
pTmpuni_nam_adr_pos = (vCard_uni_nam_adr*)malloc(sizeof(vCard_uni_nam_adr));
if(NULL == pTmpuni_nam_adr_pos)
{
pError("Get memory failure while distinct vcard info");
uni_name_adr_tmp_listfree(pTmpuni_nam_adr_head);
}
else
{
memset(pTmpuni_nam_adr_pos,0,sizeof(vCard_uni_nam_adr));
pTmpuni_nam_adr_pos->pNext = NULL;
strcpy(pTmpuni_nam_adr_pos->name,name ? name : "null");
strcpy(pTmpuni_nam_adr_pos->addr,addr ? addr : "null");
if(NULL == *pTmpuni_nam_adr_head){
*pTmpuni_nam_adr_head = pTmpuni_nam_adr_pos;
}
else{
pTmpuni_nam_adr_next->pNext = pTmpuni_nam_adr_pos;
}
}
return 0;
}
int main(void){
vCard_uni_nam_adr * pTmpuni_nam_adr_head = NULL;
check_distinct_nam_adr(&pTmpuni_nam_adr_head,"nihao","188888");
check_distinct_nam_adr(&pTmpuni_nam_adr_head,"hello","55555");
check_distinct_nam_adr(&pTmpuni_nam_adr_head,"nihao","188888");
check_distinct_nam_adr(&pTmpuni_nam_adr_head,"hello","188888");
check_distinct_nam_adr(&pTmpuni_nam_adr_head,"qqqq","000000");
vCard_uni_nam_adr * pp = pTmpuni_nam_adr_head;
while(pp != NULL){
// sleep(1);
printf("name:%s,addr:%s\n",pp->name,pp->addr);
pp = pp->pNext;
}
printf("==================\n");
uni_name_adr_tmp_listfree(&pTmpuni_nam_adr_head);
vCard_uni_nam_adr *xp = pTmpuni_nam_adr_head;
while(xp != NULL){
// sleep(1);
printf("name:%s,addr:%s\n",xp->name,xp->addr);
xp = xp->pNext;
}
}
我发现一个问题 应该是在上面标红的地方, 我把pos指向了adr所指向的内容, 但是把pos指向的内容释放了并置null后, adr这个指针还是指向这个释放后的空间..所以再访问adr的时候,会出现段错误.
因此需要将adr这个指针也置null,这样就不会出错了..
不知道我这样理解的对不对...
作者:
linux_c_py_php
时间:
2013-07-26 11:16
就个C语言基础, 自己学把, 讨论什么劲.
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2