急,C语言内存使用疑难,何时new不是问题,何时delete才是难点。

从杰 2008-09-03 03:40:30
#include "stdafx.h"
#include "stdio.h"
#include "string.h"

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

//#include "debug_new.h"

void Merge(int* In,int* Out,int i,int m,int n)
{//将有序的In[i..m]和In[m+1..n]归并为有序的Out[i..n]
int j,k;
for(j=m+1,k=i;i<=m && j<=n;++k)
{
if(In[i] < In[j])
Out[k] = In[i++];
else
Out[k] = In[j++];
}
// if(i<=m) Out[k..n] = In[i..m];
if(i<=m)
{
while(k<=n)
{
Out[k] = In[i];
k++;
i++;
}
}
// if(j<=n) Out[k..n] = In[j..n];
if(j<=n)
{
while(k<=n)
{
Out[k] = In[j];
k++;
j++;
}
}
}

int* MSort(int* In,int* Out1,int s,int t)
{//将In[s..t]归并排序为Out1[s..t]
int m;
// int Out2[10];
int* Out2 = NULL;
Out2 = (int*)malloc(t*sizeof(int));
// int* Out2 = (int*)malloc(1);
if(Out2 == NULL)
return Out2; //分配内存失败
if(s == t)
{
Out1[s] = In[s];
// free(Out2);
}
else
{
m = (s+t)/2; //将In[s..t]平分为In[s..m]和In[m+1..t]
MSort(In,Out2,s,m); //递归In[s..m]归并为有序的Out2[s..m]
MSort(In,Out2,m+1,t); //递归In[m+1..t]归并为有序的Out2[m+1..t]
Merge(Out2,Out1,s,m,t); //将Out2[s..m]和Out2[m+1..t]归并到Out1[s..t]
}
return Out2;
}

int main(int argc, char* argv[])
{
_CrtMemState s1, s2, s3; // 声明内存状态结构变量
_CrtMemCheckpoint( &s1 );// 获取第一个内存状态快照

int in[]= {2,6,45,7,79,32,5,12,15,25};
int out[10];
memset(out,0,10*sizeof(int));
MSort(in,out,0,9);
for(int i=0;i<10;i++)
printf("%d ",out[i]);
printf("\n");

_CrtMemCheckpoint( &s2 );// 获取第二个内存状态快照
// 比较两个内存快照的差异
if ( _CrtMemDifference( &s3, &s1, &s2) )
_CrtMemDumpStatistics( &s3 );// dump 差异结果
// 输出内存泄漏报告,显示在 Output 窗口的 Debug 页中
_CrtDumpMemoryLeaks();
return 0;
}
上面的程序,是用对整型数组in的归并排序处理。在函数MSort中,有这行代码:
Out2 = (int*)malloc(t*sizeof(int));分配了堆内存,但是我不知道在何处添加free语句才能正确的释放内存
我已经试过很多地方了,都是要么不能完全释放掉已经分配的内存,要么是程序得不得运行结果,难道在这里分配了内存后,就不可能在释放掉已经分配的堆内存了?请各位高手指点一下。
...全文
386 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
shangyangguanzhong 2012-08-14
  • 打赏
  • 举报
回复
几好的
kalaikaqu 2010-06-12
  • 打赏
  • 举报
回复
沙发呢 我还准备坐下看看呢 。。。
地下室都不给 下水道了下水道了
从杰 2008-09-03
  • 打赏
  • 举报
回复
不能看到下一页
从杰 2008-09-03
  • 打赏
  • 举报
回复
看来,确实不能在递归函数中分配内存啊。
从杰 2008-09-03
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 wangdeqie 的回复:]
C/C++ code
//改了下代码,这么写肯定不会内存泄漏,有些问题既然不必要,又不好解决,就尽量避免啊^_^
#include "stdio.h"
#include "string.h"

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

void Merge(int a[],int low,int middle,int high)
{
int h,i,j,k;
int b[10];
h=low;
i=low;
j=middle+1;

while(h<=middle&&j<=high)
{
i…
[/Quote]
现在只需要把Merge函数这样改一下,就可以了,终于没有内存泄露了...

void Merge(int a[],int low,int middle,int high)
{
int h,i,j,k;
// int b[10];
int* b = NULL;
b = (int*)malloc((high+1)*sizeof(int));
h=low;
i=low;
j=middle+1;

while(h<=middle&&j<=high)
{
if(a[h]<=a[j])
{
b[i]=a[h];
h++;
}
else
{
b[i]=a[j];
j++;
}
i++;
}
if(h>middle)
{
for(k=j;k<=high;k++)
{
b[i]=a[k];
i++;
}
}
else
{
for(k=h;k<=middle;k++)
{
b[i]=a[k];
i++;
}
}
for(k=low;k<=high;k++)
a[k]=b[k];
free(b);
}
hmsuccess 2008-09-03
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 CSYNYK 的回复:]
呵呵!这段的代码还是有用得着的时候啊!楼主可以去看看!把那几个函数添加到你的代码里面就应该没问题呢!
http://blog.csdn.net/CSYNYK/archive/2008/09/01/2861979.aspx
[/Quote]
学习。。。。
wangdeqie 2008-09-03
  • 打赏
  • 举报
回复

//改了下代码,这么写肯定不会内存泄漏,有些问题既然不必要,又不好解决,就尽量避免啊^_^
#include "stdio.h"
#include "string.h"

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

void Merge(int a[],int low,int middle,int high)
{
int h,i,j,k;
int b[10];
h=low;
i=low;
j=middle+1;

while(h<=middle&&j<=high)
{
if(a[h]<=a[j])
{
b[i]=a[h];
h++;
}
else
{
b[i]=a[j];
j++;
}
i++;
}
if(h>middle)
for(k=j;k<=high;k++)
{
b[i]=a[k];
i++;
}
else
{
for(k=h;k<=middle;k++)
{
b[i]=a[k];
i++;
}
}
for(k=low;k<=high;k++)
{
a[k]=b[k];
}
}

int MSort(int* In,int low,int high)
{//将In[s..t]自身归并排序
int middle;
if (low<high)
{
middle= (low+high)/2; //将In[s..t]平分为In[s..m]和In[m+1..t]
MSort(In,low,middle); //递归In[s..m]归并为有序的Out2[s..m]
MSort(In,middle+1,high); //递归In[m+1..t]归并为有序的Out2[m+1..t]
Merge(In,low,middle,high); //将Out2[s..m]和Out2[m+1..t]归并到Out1[s..t]
}
return 0;
}

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

_CrtMemState s1, s2, s3; // 声明内存状态结构变量
_CrtMemCheckpoint( &s1 );// 获取第一个内存状态快照

int in[]= {2,6,45,7,79,32,5,12,15,25};


MSort(in,0,9);
for(int i=0;i <10;i++)
printf("%d ",in[i]);
printf("\n");

_CrtMemCheckpoint( &s2 );// 获取第二个内存状态快照
// 比较两个内存快照的差异
if ( _CrtMemDifference( &s3, &s1, &s2) )
_CrtMemDumpStatistics( &s3 );// dump 差异结果
// 输出内存泄漏报告,显示在 Output 窗口的 Debug 页中
_CrtDumpMemoryLeaks();
return 0;
}


从杰 2008-09-03
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 CSYNYK 的回复:]
你再仔细推敲一下,m会不会越界?------另外给个建议:尽量不要去用递归,更何况里面还要分配内存!
[/Quote]
m不会越界吧,至于把这个递归改为非递归,那样比较复杂。
不如不用堆内存,用栈内存,或vector之类的,更加方便。
从杰 2008-09-03
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 zmlovelx 的回复:]
把资源分配封装到一个类中,使用析构函数进行释放,这样就不用到处检测哪里要自己释放了.
[/Quote]
封装后,内存泄露的情况等同于下面代码的内存泄露情况

int* Out2 = (int*)malloc(t*sizeof(int));
if(s == t)
{
Out1[s] = In[s];
free(Out2);
}
从杰 2008-09-03
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 zmlovelx 的回复:]
把资源分配封装到一个类中,使用析构函数进行释放,这样就不用到处检测哪里要自己释放了.
[/Quote]
我是这样封装的

class MemCtrl
{
public:
MemCtrl();
MemCtrl(int size);
virtual ~MemCtrl();
static int* p;
};
// implementation of the MemCtrl class.
int* MemCtrl::p = NULL;
MemCtrl::MemCtrl()
{
}

MemCtrl::~MemCtrl()
{
if(p != NULL)
delete []p;
p = NULL;
}

MemCtrl::MemCtrl(int size)
{
p = new int[size];
}

调用的时候,这样做:
MemCtrl mem(t);
int* Out2 = mem.p;
结果还是有内存泄露,只是原来泄露384字节,封装后泄露204字节,不知道怎么回事
原来的:
0 bytes in 0 Free Blocks.
384 bytes in 19 Normal Blocks.
4096 bytes in 1 CRT Blocks.
0 bytes in 0 Ignore Blocks.
0 bytes in 0 Client Blocks.
Largest number used: 4480 bytes.
Total allocations: 4480 bytes.
Detected memory leaks!
封装后的:
0 bytes in 0 Free Blocks.
204 bytes in 9 Normal Blocks.
4096 bytes in 1 CRT Blocks.
0 bytes in 0 Ignore Blocks.
0 bytes in 0 Client Blocks.
Largest number used: 4300 bytes.
Total allocations: 4480 bytes.
Detected memory leaks!
_石头_ 2008-09-03
  • 打赏
  • 举报
回复
你再仔细推敲一下,m会不会越界?------另外给个建议:尽量不要去用递归,更何况里面还要分配内存!
_石头_ 2008-09-03
  • 打赏
  • 举报
回复
很有可能是你这个参数m的问题:tmp2=MSort(In,Out2,m+1,t); //估计是嵌套调用的时候因为m越界,损坏了malloc分配区域的头信息呢!所以无法释放!我单步跟踪了一下,释放的时候tmp2的值是正确的,但是一释放就出错!
帅得不敢出门 2008-09-03
  • 打赏
  • 举报
回复
把资源分配封装到一个类中,使用析构函数进行释放,这样就不用到处检测哪里要自己释放了.
从杰 2008-09-03
  • 打赏
  • 举报
回复
我单步调试了,出错时,m = 1,s = 0
_石头_ 2008-09-03
  • 打赏
  • 举报
回复
你单步调试一下看看是哪个点出错了?我再也看看!
从杰 2008-09-03
  • 打赏
  • 举报
回复

#include "stdafx.h"
#include "stdio.h"
#include "string.h"

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

//#include "debug_new.h"

void Merge(int* In,int* Out,int i,int m,int n)
{//将有序的In[i..m]和In[m+1..n]归并为有序的Out[i..n]
int j,k;
for(j=m+1,k=i;i<=m && j<=n;++k)
{
if(In[i] < In[j])
Out[k] = In[i++];
else
Out[k] = In[j++];
}
// if(i<=m) Out[k..n] = In[i..m];
if(i<=m)
{
while(k<=n)
{
Out[k] = In[i];
k++;
i++;
}
}
// if(j<=n) Out[k..n] = In[j..n];
if(j<=n)
{
while(k<=n)
{
Out[k] = In[j];
k++;
j++;
}
}
}

int* MSort(int* In,int* Out1,int s,int t)
{
int m;
int* Out2 = NULL;
int *tmp1=NULL, *tmp2=NULL; //增加两个临时指针变量用于接收递归调用的返回值
Out2 = (int*)malloc(t*sizeof(int));
if(Out2 == NULL)
return Out2; //分配内存失败
if(s == t)
Out1[s] = In[s];
else
{
m = (s+t)/2;
tmp1=MSort(In,Out2,s,m); //接收下一级递归返回来的地址
tmp2=MSort(In,Out2,m+1,t);
Merge(Out2,Out1,s,m,t);
}
if(tmp1!=NULL) //判断是否分配了内存
free(tmp1); //释下一级递归放返回来的空间
if(tmp2!=NULL)
free(tmp2);
return Out2; //递归调用最开始一级的OUT2就要在主函数中去释放了。
}

int main(int argc, char* argv[])
{
_CrtMemState s1, s2, s3; // 声明内存状态结构变量
_CrtMemCheckpoint( &s1 );// 获取第一个内存状态快照

int in[]= {2,6,45,7,79,32,5,12,15,25};
int out[10];
MSort(in,out,0,9);
for(int i=0;i<10;i++)
printf("%d ",out[i]);
printf("\n");
free(out);

_CrtMemCheckpoint( &s2 );// 获取第二个内存状态快照
// 比较两个内存快照的差异
if ( _CrtMemDifference( &s3, &s1, &s2) )
_CrtMemDumpStatistics( &s3 );// dump 差异结果
// 输出内存泄漏报告,显示在 Output 窗口的 Debug 页中
_CrtDumpMemoryLeaks();
return 0;
}

我就是照你的方法做的,结果报错了。
_石头_ 2008-09-03
  • 打赏
  • 举报
回复
把你修改后的代码贴出来看看!按c\c++格式贴代码
从杰 2008-09-03
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 hqin6 的回复:]
引用 13 楼 CSYNYK 的回复:
修改了一下!lz试试看!

C/C++ code
int* MSort(int* In,int* Out1,int s,int t)
{
int m;
int* Out2 = NULL;
int *tmp1=NULL, *tmp2=NULL; //增加两个临时指针变量用于接收递归调用的返回值
Out2 = (int*)malloc(t*sizeof(int));
if(Out2 == NULL)
return Out2; //分配内存失败
if(s == t)
O…
[/Quote]
确实报错了,
“Debug Error! DAMAGE:after Normal block(#47)at 0x00430030”
_石头_ 2008-09-03
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 mu399 的回复:]
虽然知道了问题出在这里,但我还是不知道应该怎么改啊。只知道最简单的办法是用int Out2[10];用栈内存分配替换堆堆内存分配,这样做的缺点就是不够灵活。
[/Quote]
呵呵!你用14楼贴出来的方法试试看?看有没有什么效果?
从杰 2008-09-03
  • 打赏
  • 举报
回复
虽然知道了问题出在这里,但我还是不知道应该怎么改啊。只知道最简单的办法是用int Out2[10];用栈内存分配替换堆堆内存分配,这样做的缺点就是不够灵活。
加载更多回复(18)

69,382

社区成员

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

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