主题:请教vc中有关用new申请动态内存的问题 谢谢!
那位朋友能先解释一下动态内存分配与静态内存分配的相关基础,他们各是在什么时间分配的空间。
我在程序中是这样做的:在函数BmpToStructImage(m_hDIB)中用new分配了内存空间,该函数返回指向该空间的指针 lp(在该函数中并没有delete lp),在函数void CSIIDlg::OnColorCluster()中,直接这样调用PixelCol * ImageData=BmpToStructImage(m_hDIB);使用刚才申请的空间。 不知这样妥当否,是否会内存泄露。
void CSIIDlg::OnColorCluster()
{
#define A 7
CDlgCluster dlg;
if(dlg.DoModal()!=IDOK)
{
return ;
}
int i,j,l;
int Count=0;//当前的聚类数
Set* lpSet=new Set[dlg.m_P];
[color=FF0000] PixelCol * ImageData=BmpToStructImage(m_hDIB);[/color]
LPSTR lpDIB; // 指向DIB的指针
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB); // 锁定DIB
DWORD dwWidth = DIBWidth(lpDIB);
DWORD dwHeight =DIBHeight(lpDIB);
PixelCol y;
BYTE err=0;
int cluster;//将要加入的聚类
for (i=0;i<dlg.m_P;i++)
{
lpSet[i].CreateMemory(dwHeight,dwWidth);
}
for( j=0;j<dwHeight-100;j++)
for( i=0;i<dwWidth-100;i++)
{
y=ImageData[j*dwWidth+i];
if(0==Count)
{ lpSet[0].lpCurrent=lpSet[0].lpCpoint;
lpSet[0].lpCurrent->x=(LONG)i;
lpSet[0].lpCurrent->y=(LONG)j;
lpSet[0].lpCurrent++;
lpSet[0].MeanValue=y;
lpSet[0].Total++;
Count++;
continue;
}
cluster=FindMinError(y,err,Count,lpSet);
if(err<dlg.m_R) AddPixToSet(i,j,lpSet+cluster,y);
else
{ l=Count;
Count++;
//检测目前聚类数Count是否大于期望聚类数m_P,若是则更新聚类半径m_R
if(Count>dlg.m_P)
{dlg.m_R=dlg.m_R+(Count-dlg.m_P)*A*dlg.m_R/dlg.m_P;
Count=0, i=-1, j=0;
for(int k=0;k<dlg.m_P;k++)
{ lpSet[k].Total=0;
}
continue;
}
lpSet[l].lpCurrent=lpSet[l].lpCpoint;
lpSet[l].lpCurrent->x=i;
lpSet[l].lpCurrent->y=j;
lpSet[l].lpCurrent++;
lpSet[l].MeanValue=y;
lpSet[l].Total++;
}
}
}
PixelCol* BmpToStructImage(HDIB hDIB)
{ LPSTR lpDib;
LPSTR lpDIBBits;
PixelCol * lp;
LPBITMAPINFOHEADER lpBi;
//锁定输入内存
lpDib = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
lpBi = (LPBITMAPINFOHEADER)lpDib;
//如果不是24位图,返回NULL
if(lpBi->biBitCount != 24)
{
return NULL;
}
lpBi = (LPBITMAPINFOHEADER)lpDib;
DWORD dwWidth = lpBi->biWidth;
DWORD dwHeight = lpBi->biHeight;
DWORD dwLineBytes = (DWORD)WIDTHBYTES(dwWidth * 24);
//申请BufSize大小的内存空间
DWORD BufSize=dwWidth*dwHeight;
[color=FF0000]lp= new PixelCol[BufSize];[/color]
if (lp==0)
{
AfxMessageBox("申请空间错误");
}
lpDIBBits=::FindDIBBits(lpDib);//找到DIB图像像素起始位置
int i,j;
for(j=0;j<dwHeight;j++)
for(i=0;i<dwWidth;i++)
{
lp[j*dwWidth+i].b=lpDIBBits[j*dwLineBytes+i*3+0];
lp[j*dwWidth+i].g=lpDIBBits[j*dwLineBytes+i*3+1];
lp[j*dwWidth+i].r=lpDIBBits[j*dwLineBytes+i*3+2];
}
[color=800080]return lp;[/color]
}
我在程序中是这样做的:在函数BmpToStructImage(m_hDIB)中用new分配了内存空间,该函数返回指向该空间的指针 lp(在该函数中并没有delete lp),在函数void CSIIDlg::OnColorCluster()中,直接这样调用PixelCol * ImageData=BmpToStructImage(m_hDIB);使用刚才申请的空间。 不知这样妥当否,是否会内存泄露。
void CSIIDlg::OnColorCluster()
{
#define A 7
CDlgCluster dlg;
if(dlg.DoModal()!=IDOK)
{
return ;
}
int i,j,l;
int Count=0;//当前的聚类数
Set* lpSet=new Set[dlg.m_P];
[color=FF0000] PixelCol * ImageData=BmpToStructImage(m_hDIB);[/color]
LPSTR lpDIB; // 指向DIB的指针
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB); // 锁定DIB
DWORD dwWidth = DIBWidth(lpDIB);
DWORD dwHeight =DIBHeight(lpDIB);
PixelCol y;
BYTE err=0;
int cluster;//将要加入的聚类
for (i=0;i<dlg.m_P;i++)
{
lpSet[i].CreateMemory(dwHeight,dwWidth);
}
for( j=0;j<dwHeight-100;j++)
for( i=0;i<dwWidth-100;i++)
{
y=ImageData[j*dwWidth+i];
if(0==Count)
{ lpSet[0].lpCurrent=lpSet[0].lpCpoint;
lpSet[0].lpCurrent->x=(LONG)i;
lpSet[0].lpCurrent->y=(LONG)j;
lpSet[0].lpCurrent++;
lpSet[0].MeanValue=y;
lpSet[0].Total++;
Count++;
continue;
}
cluster=FindMinError(y,err,Count,lpSet);
if(err<dlg.m_R) AddPixToSet(i,j,lpSet+cluster,y);
else
{ l=Count;
Count++;
//检测目前聚类数Count是否大于期望聚类数m_P,若是则更新聚类半径m_R
if(Count>dlg.m_P)
{dlg.m_R=dlg.m_R+(Count-dlg.m_P)*A*dlg.m_R/dlg.m_P;
Count=0, i=-1, j=0;
for(int k=0;k<dlg.m_P;k++)
{ lpSet[k].Total=0;
}
continue;
}
lpSet[l].lpCurrent=lpSet[l].lpCpoint;
lpSet[l].lpCurrent->x=i;
lpSet[l].lpCurrent->y=j;
lpSet[l].lpCurrent++;
lpSet[l].MeanValue=y;
lpSet[l].Total++;
}
}
}
PixelCol* BmpToStructImage(HDIB hDIB)
{ LPSTR lpDib;
LPSTR lpDIBBits;
PixelCol * lp;
LPBITMAPINFOHEADER lpBi;
//锁定输入内存
lpDib = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
lpBi = (LPBITMAPINFOHEADER)lpDib;
//如果不是24位图,返回NULL
if(lpBi->biBitCount != 24)
{
return NULL;
}
lpBi = (LPBITMAPINFOHEADER)lpDib;
DWORD dwWidth = lpBi->biWidth;
DWORD dwHeight = lpBi->biHeight;
DWORD dwLineBytes = (DWORD)WIDTHBYTES(dwWidth * 24);
//申请BufSize大小的内存空间
DWORD BufSize=dwWidth*dwHeight;
[color=FF0000]lp= new PixelCol[BufSize];[/color]
if (lp==0)
{
AfxMessageBox("申请空间错误");
}
lpDIBBits=::FindDIBBits(lpDib);//找到DIB图像像素起始位置
int i,j;
for(j=0;j<dwHeight;j++)
for(i=0;i<dwWidth;i++)
{
lp[j*dwWidth+i].b=lpDIBBits[j*dwLineBytes+i*3+0];
lp[j*dwWidth+i].g=lpDIBBits[j*dwLineBytes+i*3+1];
lp[j*dwWidth+i].r=lpDIBBits[j*dwLineBytes+i*3+2];
}
[color=800080]return lp;[/color]
}