c/c++內存泄露测试

 相信很多人都有这样的经验,用一个指针指向一个用new或者malloc申请的动态内存,然后把改指针连接到一个链表中。

当链表做删除操作时,很多人仅是移动指针。而没有把孤立的动态内存释放掉。最近用visual leak detector测试,测试

代码如下:

               

#include <wchar.h>
#include <vld.h>
#include <iostream>

using namespace std;
class test
{
public:
    int i;
    test *next;
};

int main()
{
 test *my,*t1, *t2;
 my=new test;
 my->next = NULL;
    for(int j=0; j<10;j++)
    {
        if (j>5)
        {
            test *pt = new test;
            pt->i = j;
            pt->next = NULL;
            t1=pt;
            if(my->next == NULL)
            {
                my->next =t1;
                t2=t1;
            }
            else
            {
                t1->next=t2->next;
                t2->next=t1;
                t2=t2->next;
            }
        }
    }
    for(t1=my,my=my->next,t2=my; t2!=NULL; t2=my)
 {
  if(t1!=NULL)
  { 
   delete t1;   //这里不释放,会有内存丢失
   t1=NULL;
  }
  cout << t2->i<< endl;
  my=my->next;
  delete t2;    //这里不释放,会有内存丢失
 }
 getchar();
    return 0;
}

其实delete 是释放指针所指对象,把改对象释放了,他还可以指向其他对象。并不会使指针本身无效,

指针变量只有不在自己的作用域时,才会失效。

以下为计算机图形学VC++实现中,多边形扫描算法实现源码,个人认为内存泄露部分:

void CTestView::OnMenuAET() //菜单函数

{

        // TODO: Add your command handler code here

        AfxGetMainWnd()->SetWindowText("案例6:多边形有效边表填充算法");//显示标题

       

        CColorDialog ccd(GetColor);

        if(ccd.DoModal()==IDOK)//调用调色板选取前景色

        {

                GetColor=ccd.GetColor();

        }

        RedrawWindow();//刷新屏幕

        CreatBucket();//初始化新边

        Et();//用于建立边表     

        PolygonFill();//多边形填充   

}

 

void CTestView::CreatBucket()//建立新边结点

{

        int ScanMin,ScanMax;//确定扫描线的最小值和最大值

        ScanMax=ScanMin=Point[0].y;

        for(int i=1;i<Number;i++)

        {

                if(Point[i].y<ScanMin)

                {

                        ScanMin=Point[i].y;//扫描线的最小值                 

                }

                if(Point[i].y>ScanMax)

                {

                        ScanMax=Point[i].y;//扫描线的最大值

                }

        }      

        for(i=ScanMin;i<=ScanMax;i++)//建立新边结点

        {

                if(ScanMin==i)//新边头结点

                {

                        HeadB=new Bucket;//建立新边的头结点

                        CurrentB=HeadB;//CurrentBBucket当前结点指针

                        CurrentB->ScanLine=ScanMin;

                        CurrentB->p=NULL;//没有连接边链表

                        CurrentB->next=NULL;

                }

                else//建立新边的其它结点

                {

                        CurrentB->next=new Bucket;//新建一个新边结点

                        CurrentB=CurrentB->next;//使CurrentB指向新建的新边结点

                        CurrentB->ScanLine=i;

                        CurrentB->p=NULL;//没有连接边链表

                        CurrentB->next=NULL;                           

                }

        }

}

 

void CTestView::Et()//构造边表

{

        for(int i=0;i<Number;i++)//访问每个顶点

        {

                CurrentB=HeadB;//从新边链表的头结点开始循环

                int j=i+1;//边的第二个顶点,Point[i]Point[j]构成边

                if(j==Number) j=0;//保证多边形的闭合

                if(Point[j].y>Point[i].y)//终点比起点高

                {

                        while(CurrentB->ScanLine!=Point[i].y)//在新边内寻找该边的yMin

                        {

                                CurrentB=CurrentB->next;//移到下一个新边结点

                        }

                        E[i].x=Point[i].x;//计算AET表的值

                        E[i].yMax=Point[j].y;

                        E[i].k=double((Point[j].x-Point[i].x))/(Point[j].y-Point[i].y);//代表1/k                   

                        E[i].next=NULL;

                        CurrentE=CurrentB->p;//获得新边上链接边表的地址

                        if(CurrentB->p==NULL)//当前新边结点上没有连结边结点

                        {

                                CurrentE=&E[i];//赋边的起始地址

                                CurrentB->p=CurrentE;//第一个边结点直接连接到对应的新边中

                        }

                        else

                        {

                                while(CurrentE->next!=NULL)//如果当前边已连有边结点

                                {

                                        CurrentE=CurrentE->next;//移动指标到当前边的最后一个边结点                                  

                                }

                                CurrentE->next=&E[i];//把当前边接上去

                        }

                }

                if(Point[j].y<Point[i].y)//终点比起点低

                {

                        while(CurrentB->ScanLine!=Point[j].y)

                        {

                                CurrentB=CurrentB->next;                            

                        }

                        E[i].x=Point[j].x;

                        E[i].yMax=Point[i].y;

                        E[i].k=double((Point[i].x-Point[j].x))/(Point[i].y-Point[j].y);                    

                        E[i].next=NULL;

                        CurrentE=CurrentB->p;

                        if(CurrentE==NULL)

                        {

                                CurrentE=&E[i];

                                CurrentB->p=CurrentE;

                        }

                        else

                        {

                                while(CurrentE->next!=NULL)

                                {

                                        CurrentE=CurrentE->next;                             

                                }

                                CurrentE->next=&E[i];

                        }

                }

        }

        CurrentB=NULL;

        CurrentE=NULL;     

}

 

void CTestView::AddEdge(AET *NewEdge)//插入临时边表

{

        T1=HeadE;

        if(T1==NULL)//边表为空,将边表置为TempEdge

        {

                T1=NewEdge;

                HeadE=T1;

        }

        else

        {

                while(T1->next!=NULL)//边表不为空,TempEdge连在该边之后

                {

                        T1=T1->next;

                }

                T1->next=NewEdge;

        }

}

 

void CTestView::EdgeOrder()//对边表进行排序

{      

        T1=HeadE;

        if(T1==NULL)

        {

                return;

        }

        if(T1->next==NULL)//如果该边表没有再连边表

        {

                return;//新边结点只有一条边,不需要排序

        }

        else

        {

                if(T1->next->x<T1->x)//边表按x值排序

                {

                        T2=T1->next;

                        T1->next=T2->next;

                        T2->next=T1;

                        HeadE=T2;

                }

                T2=HeadE;

                T1=HeadE->next;           

                while(T1->next!=NULL)//继续两两比较相连的边表的x,进行排序

                {

                        if(T1->next->x<T1->x)

                        {

                                T2->next=T1->next;

                                T1->next=T1->next->next;

                                T2->next->next=T1;

                                T2=T2->next;

                        }

                        else

                        {

                                T2=T1;

                                T1=T1->next;

                        }

                }

        }

}

 

void CTestView::PolygonFill()//多边形填充

{

        HeadE=NULL;

        for(CurrentB=HeadB;CurrentB!=NULL;)//访问所有新边结点

        {

                for(CurrentE=CurrentB->p;CurrentE!=NULL;CurrentE=CurrentE->next)//访问新边中排序前的边结点                   

                {

            AET *TempEdge= new(AET);

                        TempEdge->x=CurrentE->x;

                        TempEdge->yMax=CurrentE->yMax;

                        TempEdge->k=CurrentE->k;

                        TempEdge->next=NULL;                

                        AddEdge(TempEdge);//将该边插入临时Aet

                }

                EdgeOrder();//使得边表按照x递增的顺序存放               

                T1=HeadE;//根据ymax抛弃扫描完的边结点

                if(T1==NULL)

                {

                        HeadB=CurrentB;   //个人添加,每次return前释放CurrentB

                        CurrentB=CurrentB->next;

                        HeadB->next=NULL;

                    delete HeadB;

                        return;

                }

                while(CurrentB->ScanLine>=T1->yMax)//放弃该结点,Aet表指针后移(下闭上开)

                {

                        T1=T1->next;

                        delete HeadE;

                        HeadE=T1;

                        if(HeadE==NULL)

                        {

                                HeadB=CurrentB;   //个人添加,每次return前释放CurrentB

                                CurrentB=CurrentB->next;

                                HeadB->next=NULL;

                        delete HeadB;

                                return;

                        }

                }

                if(T1->next!=NULL)

                {

                        T2=T1;

                        T1=T2->next;

                }

                while(T1!=NULL)

                {

                        if(CurrentB->ScanLine>=T1->yMax)//跳过一个结点

                        {

                                T2->next=T1->next;

                                T1->next=NULL;

                                delete T1;

                                T1=T2->next;

                        }

                        else

                        {

                                T2=T1;

                                T1=T2->next;

                        }

                }

                BOOL In=false;//设置一个BOOL变数In,初始值为假

                double xb,xe;//扫描线的起点和终点

                for(T1=HeadE;T1!=NULL;T1=T1->next)//填充扫描线和多边形相交的区间

                {

                        if(In==false)

                        {

                                xb=T1->x;

                                In=true;//每访问一个结点,In值取反一次

                        }

                        else//如果In值为真,则填充从当前结点的x值开始到下一结点的x值结束的区间

                        {

                                xe=T1->x-1;//左闭右开

                                CClientDC dc(this);

                                for(double x=xb;x<=xe;x++)

                                        dc.SetPixel(ROUND(x),CurrentB->ScanLine,GetColor);//填充语句

                        //     Sleep(1);//延时1ms,提高填充过程的可视性

                                In=FALSE;

                        }              

                }

                for(T1=HeadE;T1!=NULL;T1=T1->next)//边连贯性

                {

                        T1->x=T1->x+T1->k;//x=x+1/k                               

                }

                HeadB=CurrentB;          //个人添加,每次释放CurrentB

                CurrentB=CurrentB->next;

                HeadB->next=NULL;

                delete HeadB;

        }

        delete CurrentE;

        delete HeadE;

        delete HeadB;

        delete CurrentB;

       

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值