关于实参和形参

27 篇文章 1 订阅

        C++中实参和形参结合的方式有三种:传值、引用和传地址。前面两种比较简单,不用多说,这里重点说一下传地址。

         传地址一般都跟指针有关,当用指针进行动态存储分配的时候,是需要主动释放内存的,否则会出现内存泄漏。

          假设实参是一个进行动态存储分配的指针,那么,一般情况下,释放实参指针或者释放形参指针都可以,因为实参和形参指向的是同一段内存。

          对于实参和形参不是指向同一段内存的情况,则实参指针和形参指针都必须得到释放。下面给出来两段程序来说明。

#include<iostream.h>
int sum(int a[3])
{
int s=0;
for(int i=0;i<3;i++)
{
s=s+a[i];
}
//delete []a;
return s;
}
void main()
{
int s=0;
while(1)
{
while(1)
{
int *p;
p=new int[3];
   for(int i=0;i<3;i++)
{
  p[i]=1;
}
s=sum(p);
            delete []p;
break;
}
}
}


IplImage* CReadCameraDlg::strengthImage_Histogram(IplImage *img)  //直方图均衡化代码实现
{
IplImage* dst = NULL;
dst = cvCreateImage(cvGetSize(img),img->depth,img->nChannels);
int width = img->width;
    int height = img->height;
    int step = img->widthStep;
double his[256] = {0};//灰度 
    double p_hist[256]={0};//灰度比例
    double s_hist[256]={0};//累计灰度比例
    double total = img->width*img->height;//总像素数
for(int i = 0; i < height; i++)
   {
       for(int j = 0; j < width; j++)
       his[((uchar*)(img->imageData+i*step))[j]]++;//统计各灰度值的个数
   }
for(int i = 0; i < 256; i++)//计算灰度累积概率分布
   {
      p_hist[i] = (double)his[i]/total;
        if(i == 0)s_hist[i] = p_hist[i];
       else s_hist[i] = s_hist[i-1]+p_hist[i];
   }
    
    //图像增强
    for(int i = 0; i < img->height; i++)
   {
       for(int j = 0; j < img->width; j++)
       {
           ((uchar*)(i * dst->widthStep +dst->imageData))[j] = s_hist[((uchar*)(i * img->widthStep +img->imageData))[j]]*255+0.5;
       }
    } 
cvReleaseImage(&img);//主动释放形参所指向的内存地址。
                    
return dst;
}


//彩色直方图均衡化
IplImage* CReadCameraDlg::EqualizeHistColorImage(IplImage *pImage)//为什么这里的形参指向的内存地址不需要主动释放呢?
                                                             //原因在于给它传地址的实参img是由函数cvQueryFrame产生的
 //返回值,此时,系统会自动释放。
{  
IplImage *pEquaImage=NULL;
    pEquaImage = cvCreateImage(cvGetSize(pImage), pImage->depth, 3);//通常IPL图象格式可以存贮非交叉存取的图像,但是cvCreateImage函数只能创建交叉存取图像 
   // 原图像分成各通道后再均衡化,最后合并即彩色图像的直方图均衡化  
    const int MAX_CHANNEL = 4;  
    IplImage *pImageChannel[MAX_CHANNEL] = {NULL};  
//IplImage *pImageChannel0[MAX_CHANNEL] = {NULL};//******************  
    int i;  
    for (i = 0; i < pImage->nChannels; i++)  
   pImageChannel[i] = cvCreateImage(cvGetSize(pImage), pImage->depth, 1);  
    cvSplit(pImage, pImageChannel[0], pImageChannel[1], pImageChannel[2],pImageChannel[3]); //分别复制每个通道到多个单通道图像
    for (i = 0; i < pImage->nChannels; i++)  
       //cvEqualizeHist(pImageChannel[i], pImageChannel[i]);  
       //pImageChannel0[i]=strengthImage_Histogram(pImageChannel[i]);//*********************
   pImageChannel[i]=strengthImage_Histogram(pImageChannel[i]);//pImageChannel[i]首先指向了一段内存地址,作为实参后将该段内存
                                                              //地址传递给了形参img,而后,由于函数将返回值赋给了pImageChannel[i],
                                                             //所以其右指向了另一段内存地址,而形参img指向的内存地址也需要主动释放。
    cvMerge(pImageChannel[0], pImageChannel[1], pImageChannel[2],pImageChannel[3], pEquaImage);  
  
    for (i = 0; i < pImage->nChannels; i++)  

cvReleaseImage(&pImageChannel[i]);
//cvReleaseImage(&pImageChannel0[i]);//***************
}
  
    return pEquaImage;  

}  




A处代码,由于实参和左边的变量是一样的,导致了实参在传完地址后,实参指针又指向了另一块内存,所以,在这种情况下,实参指针和形参指针都要得到释放。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值