内存泄漏了么?

周晓荣 2011-12-07 11:33:06

#include <iostream>
#include <windows.h>
using namespace std;

int main(void)
{
ReRun:
int *a = new int[1024];
Sleep(1000);
goto ReRun;
//问题:win7-32位,vc6.0,在任务管理器那查看到,内存每秒增量为8K,为什么不是4K呢?

return 0;
}


还有,delete []a;应该在ReRun标签内,否则会泄漏,对吧?
...全文
1347 52 打赏 收藏 转发到动态 举报
写回复
用AI写文章
52 条回复
切换为时间正序
请发表友善的回复…
发表回复
周晓荣 2011-12-09
  • 打赏
  • 举报
回复
[Quote=引用 51 楼 demon__hunter 的回复:]

还有分分吗?
[/Quote]
你来迟了!下次请准备好闹钟。
hzhrh 2011-12-08
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 qscool1987 的回复:]
引用 17 楼 et214721856 的回复:
引用 10 楼 demon__hunter 的回复:

从很多实现来看,new int[1024]中实际向os申请的内存可能比1024*sizeof(int)要大一些。
比如多出来的一部分内存作为分配相关信息cookie,另外我记得vc9 debug下实际向os申请的内存是俺8字节对齐的。

发现了点小问题,发现第一次new的时候,任务……
[/Quote]

你在任务管理器中看的,是否可能你机器运行的东西较多,或CPU处理没那么快到任务管理器显示就休眠,所以,你看到的都是8K,其实都是前一次已经休眠的原因。
你将Sleep放到new前面试下看看。
yangguangjianke 2011-12-08
  • 打赏
  • 举报
回复
刚才在同事机器上试了一下,好像win7任务管理器更新是两秒钟一次吧。
我过路的,就当我不懂!~
疯狂鸭子 2011-12-08
  • 打赏
  • 举报
回复
声明指针后要释放,不然肯定会内存泄漏~
机智的呆呆 2011-12-08
  • 打赏
  • 举报
回复
还有分分吗?
ssissi821 2011-12-08
  • 打赏
  • 举报
回复
new和delete是一对的,至少有个delete啊!
周晓荣 2011-12-08
  • 打赏
  • 举报
回复
[Quote=引用 48 楼 zhangleijie2010 的回复:]
楼主,以前听一个老教授讲堆的时候说到过,堆是有缓冲池的,缓冲池具体多大不是很清楚,很有可能是8K,这个数字是我根据你的问题猜的哈,哈哈。new的时候应该是先经过堆的缓冲池再到堆的,4K可能没充满缓冲池。
而且还记得有个人给我说过,缓冲池有个特性,如果在整个new的空间不超过它的大小的话,你不主动去释放也没事,系统活编译器会帮你搞定的。
[/Quote]
有没有先经过缓冲池这个难以判断吧?
HeapAlloc每次提交一个页,确实是增加了4K内存
而new最终是通过HeapAlloc来实现的,所以new调用HeapAlloc一次是提交多少页这个能否查得到呢?
zhangleijie2010 2011-12-08
  • 打赏
  • 举报
回复
楼主,以前听一个老教授讲堆的时候说到过,堆是有缓冲池的,缓冲池具体多大不是很清楚,很有可能是8K,这个数字是我根据你的问题猜的哈,哈哈。new的时候应该是先经过堆的缓冲池再到堆的,4K可能没充满缓冲池。
而且还记得有个人给我说过,缓冲池有个特性,如果在整个new的空间不超过它的大小的话,你不主动去释放也没事,系统活编译器会帮你搞定的。
周晓荣 2011-12-08
  • 打赏
  • 举报
回复
[Quote=引用 46 楼 yisikaipu 的回复:]

引用 40 楼 et214721856 的回复:总之就是多调拨1页
其中4K直接返回给你,剩下的4K备用
这两个答案有没有冲突?

我认为这里是这样的,你要4k,堆不可能刚好容你4k,反正没那么完美

如果你只要2k,那么好的,堆给你2k,而且也不会跟系统再要4k备用

后面的代码你可以观察,与我在#29楼说的一致,但是不完美的程度的比我之前认为的大,就是说,你向4k的堆要2.5……
[/Quote]
楼主表示十分感谢yisikaipu 和 Demon__Hunter的热心帮助
特别是yisikaipu
以下链接是感谢贴,请两位接分吧。
由于等级不够,只能发100分的!
http://topic.csdn.net/u/20111208/15/012a3166-c38f-4f3d-bfae-e120dbc986bf.html

yisikaipu 2011-12-08
  • 打赏
  • 举报
回复
[Quote=引用 40 楼 et214721856 的回复:]总之就是多调拨1页
其中4K直接返回给你,剩下的4K备用
这两个答案有没有冲突?[/Quote]

我认为这里是这样的,你要4k,堆不可能刚好容你4k,反正没那么完美

如果你只要2k,那么好的,堆给你2k,而且也不会跟系统再要4k备用

后面的代码你可以观察,与我在#29楼说的一致,但是不完美的程度的比我之前认为的大,就是说,你向4k的堆要2.5k没问题,你要3k(算不上是接近于4k)就不够了,堆就要跟系统再要4k

#32楼多次提到new的最终调用是HeapAlloc,所以下面就直接用HeapAlloc示例了

// vs2008 win7
#include <iostream>
#include <windows.h>
#include <conio.h>
using namespace std;

int main()
{
cout <<"情况1" <<endl;
{
HANDLE hp=HeapCreate(0,0,1); // 提交4k。随便写个小于4k的数,表示堆大小限制为4k,不可自动增长
void *p=HeapAlloc(hp,0,2*1024); // 申请从4k的堆里分配2k

if(p)
cout <<"2k:\t" <<p <<endl;

HeapFree(hp,0,p); // 注释掉这行试试

void *q=HeapAlloc(hp,0,2*1024); // 2k

if(q)
cout <<"2k:\t" <<q <<endl;

HeapDestroy(hp);
}

cout <<endl <<"情况2" <<endl;
{
HANDLE hp=HeapCreate(0,0,1); // 提交4k。限制最大4k
void *p=HeapAlloc(hp,0,3*1024); // 申请分配3k,能成功吗?

if(p)
cout <<"3k:\t" <<p <<endl;
else
{
void *q=HeapAlloc(hp,0,2.5*1024); // 2.5k

if(q)
cout <<"2.5k:\t" <<q <<endl;
}

HeapDestroy(hp);
}

cout <<endl <<"情况3" <<endl;
{
HANDLE hp=HeapCreate(0,0,0); // 提交4k。堆大小无限制,可自动增长
void *p=HeapAlloc(hp,0,3*1024); // 申请分配3k,可以,堆自动增长4k

if(p)
{
cout <<"3k:\t" <<p <<endl;

HeapFree(hp,0,p);

void *q=HeapAlloc(hp,0,4*1024); // 4k呢,也可以,堆自动增长4k

if(q)
cout <<"4k:\t" <<q <<endl;
}

HeapDestroy(hp);
}

cout <<endl <<"情况4:请按键,然后观察任务管理器内存增长,大约30秒" <<endl;
_getch();
{
HANDLE hp=HeapCreate(0,0,0);
for(int i=0;i<60;++i) // 大约每隔2秒,堆自动增长4k
{
void *p=HeapAlloc(hp,0,1024);
Sleep(500);
}

HeapDestroy(hp);
}

return 0;
}
  • 打赏
  • 举报
回复
任务管理器里面更新速度改成“高”或者“低”再看看
wake2010 2011-12-08
  • 打赏
  • 举报
回复
系统内存管理器,分页块最小为4k。
一次分配其它开销。
追求执着 2011-12-07
  • 打赏
  • 举报
回复

好幽默的楼主啊!!不知道你想要问什么呢
机智的呆呆 2011-12-07
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 yisikaipu 的回复:]
引用 18 楼 et214721856 的回复:如果int *a = new [2048];一次性new 8k,任务管理器就会立刻增加内存了!

应该是windows堆内存调拨粒度为8k的原因吧,与那些什么字节对齐应该没关系
[/Quote]
对,从lz描述情况来看是应该这样的。
vc operator new 函数很早以前debug过,现在记不清楚了~~
跟下operator new 函数实现源码,就知道原因了。
多喝水ooo 2011-12-07
  • 打赏
  • 举报
回复
我也觉得应该是和系统有关系。。。代码上应该每次就是4k。。
善良超锅锅 2011-12-07
  • 打赏
  • 举报
回复
明显故意泄露了
yisikaipu 2011-12-07
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 et214721856 的回复:]如果int *a = new [2048];一次性new 8k,任务管理器就会立刻增加内存了![/Quote]

应该是windows堆内存调拨粒度为8k的原因吧,与那些什么字节对齐应该没关系
周晓荣 2011-12-07
  • 打赏
  • 举报
回复
如果int *a = new [2048];一次性new 8k,任务管理器就会立刻增加内存了!
周晓荣 2011-12-07
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 demon__hunter 的回复:]

从很多实现来看,new int[1024]中实际向os申请的内存可能比1024*sizeof(int)要大一些。
比如多出来的一部分内存作为分配相关信息cookie,另外我记得vc9 debug下实际向os申请的内存是俺8字节对齐的。
[/Quote]
发现了点小问题,发现第一次new的时候,任务管理器显示的内存并没有增加,然后第二次new才增加8K,第三次不增加,第四次又增加8K,就是new两次刚好8K,任务管理器才显示内存增加
每次NEW两次,内存才增加8K

为什么这么神奇的
周晓荣 2011-12-07
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 demon__hunter 的回复:]

从很多实现来看,new int[1024]中实际向os申请的内存可能比1024*sizeof(int)要大一些。
比如多出来的一部分内存作为分配相关信息cookie,另外我记得vc9 debug下实际向os申请的内存是俺8字节对齐的。
[/Quote]
你的回答比较靠谱
加载更多回复(32)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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