简单的程序,特殊的内存“泄露”。

lonelybug 2009-03-31 02:15:23
帮忙看一下下面这段代码
char **text=(char **)malloc(sizeof(char*)*1000000);
memset(text,0,1000000);
for(jj=0;jj<1000000;jj++)
{
text[jj]=(char *)malloc(sizeof(char)*255);
memset(text[jj],'\0',255);
}
for(jj=0;jj<1000000;jj++)
{
free(text[jj]);
//printf("%s\n",text[jj]);
text[jj]=NULL;

}
free(text);
text=NULL;

这个程序运行之后,会产生20MB组有的内存占用。但是如果只是
char **text=(char **)malloc(sizeof(char*)*1000000);
memset(text,0,1000000);
free(text);
text=NULL;

则只会有1.2MB左右的内存占用。不知道是不是我的程序有内存泄露,还是因为什么其它原因!?

我用的是C语言,不要提出delete, new这种建议,谢谢。


...全文
151 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Depraved_Survival 2009-03-31
  • 打赏
  • 举报
回复
跟我遇到的问题类似,LZ可以看下这个帖子
http://topic.csdn.net/u/20090305/18/01ca45d4-5727-4180-a2dc-3e4d0808a5b3.html

我觉得单凭LZ对内存的观察,无法判断内存是否泄漏。
首先,char **text=(char **)malloc(sizeof(char*)*1000000),运行后理论分配3.815M。
根据我过去的实验(WIndows Mobile下)程序中内存的new和malloc操作后,操作系统并不会从系统堆中马上分出这部分内存,而是先判断该内存是否已经被使用,如果是则马上分配,否则系统会等待直到内存区域被使用。无论你申请的内存是多少,系统一次都只会给你分配最小可分配块的倍数。我在Windows Mobile操作系统上实验出的最小内存块为4096B,delete和free也一样,不会马上回归系统堆。因此free或delete后内存并没有恢复到new和malloc之前的水平,这是合理的。

不知道LZ所观察的1.2MB是不是在free后?如果在free后是合理的,如果在free前的话,我觉得还需要在Windows下实验一下,申请的内存区域如果不使用,那么申请多少以后才会分配?还是不使用就不分配。

另外,下面代码运行后,内存理论分配值为1000000*1*255/1024/1024=243.18MB,同上,如果是free后的话是合理的。
for(jj=0;jj <1000000;jj++)
{
text[jj]=(char *)malloc(sizeof(char)*255);
memset(text[jj],'\0',255);
}
xiaocha 2009-03-31
  • 打赏
  • 举报
回复
写成下面这样,看得清楚点:)

#define TEXT_COUNT 1000000
#define TEXT_LEN 255
typedef char * TEXT;

TEXT *text = (TEXT *)malloc(sizeof(TEXT) * TEXT_COUNT);

memset(text, 0, TEXT_COUNT); // 多余,后面每个都赋值了,虽然是好习惯,但耗时不少

for (j=0; j<TEXT_COUNT; j++)
{
text[j] = (char *)malloc(sizeof(char *) * TEXT_LEN);
memset(text[j], 0, TEXT_LEN);
}

for (j=0; j<TEXT_COUNT; j++)
{
free(text[j]);
text[j] = NULL; // 多余,马上就释放text了,虽然是好习惯,但耗时不少
}

free(text);
text = NULL; // 很好,多一个没关系
insulted 2009-03-31
  • 打赏
  • 举报
回复

char **text=(char **)malloc(sizeof(char*)*1000000);
memset(text,0,1000000); //最好是memset(text,0,sizeof(char*)*1000000);虽然任何类型的指针大小一样
for(jj=0;jj <1000000;jj++)
{
text[jj]=(char *)malloc(sizeof(char)*255);
memset(text[jj],'\0',255);
}
for(jj=0;jj <1000000;jj++)
{
free(text[jj]);
//printf("%s\n",text[jj]);
text[jj]=NULL;

}
free(text);
text=NULL;
freshairfly 2009-03-31
  • 打赏
  • 举报
回复
LZ可以把你的程序最小化一段时间,然后再查看内存占用情况,我觉得,你所说的两种情况占用的内存(我估计你这里是指物理内存)应该就差不多了

如果真要查找内存泄漏,可以用一些工具,比如BoundsChecker,和RuntimeChecker
freshairfly 2009-03-31
  • 打赏
  • 举报
回复
不知道LZ所谓的“1.2MB左右的内存占用”之类的数据是指什么数据,因为一个进程有几个内存指标:
1.物理内存
2.虚拟内存
3.虚拟字节(virtual bytes)

首先物理内存又叫working set,这个跟很多东西有关系,比如你的程序在后台很久不活动了,OS就会把你程序占用的物理内存swap到磁盘的页上
,另外还和OS的内存管理策略有关系,XP比较保守,Vista则比较奔放。

虚拟内存是指你总共占用的虚拟地址,包括Reverse,Commit。。。等
而虚拟字节概念和虚拟内存比较类型,不过好像不包括Reverse的地址空间

因为你即使启动了一个最简单的Hello World,因为它要加载系统相关的DLL,而这些DLL本身也是要占用虚拟地址空间的,所以通过以上几个参数,都不足以判断程序是否内存泄漏,也不足以判断真实的内存占用情况
changhe325 2009-03-31
  • 打赏
  • 举报
回复
学习下
liliangbao 2009-03-31
  • 打赏
  • 举报
回复
char **text=(char **)malloc(sizeof(char*)*1000000); 
memset(text,0,1000000); //应该是memset(text,0,sizeof(int*)*1000000);
for(jj=0;jj <1000000;jj++)
{
text[jj]=(char *)malloc(sizeof(char)*255);
memset(text[jj],'\0',255);
}
for(jj=0;jj <1000000;jj++)
{
free(text[jj]);
//printf("%s\n",text[jj]);
text[jj]=NULL;

}
free(text);
text=NULL;

我认为程序这样动态使用二维数组没有问题!
高人指点~共勉!
mengde007 2009-03-31
  • 打赏
  • 举报
回复
text = (char **)malloc( sizeof(char *)*1000000) ;
*text仍然是指针,所以 *(text+i) = (char *)malloc(sizeof(char)sizeof(char)*255)
mengde007 2009-03-31
  • 打赏
  • 举报
回复
貌视不能这样分配内存吧
yyyapple 2009-03-31
  • 打赏
  • 举报
回复
释放之后之所以会占用内存,可能的结果是堆有缓存
yyyapple 2009-03-31
  • 打赏
  • 举报
回复
        char **text=(char **)malloc(sizeof(char*)*1000000);  //这里4M
memset(text,0,1000000);
for(jj=0;jj <1000000;jj++)
{
text[jj]=(char *)malloc(sizeof(char)*255); //这里1000000*255 = 255M

总共260M


char **text=(char **)malloc(sizeof(char*)*1000000); //这里4M
memset(text,0,1000000);
free(text);
text=NULL;

69,369

社区成员

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

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