释放指针

时间:2010-11-11 04:05:15

标签: c++ pointers stl

我有一个A类型(名为ListA)容器的列表指针,指针B的向量。(每个A对象是一个具有私有属性的容器类:std<vector> *B)。然后,我声明一个指针(称为C与A具有相同的类型),通过ListA进行for循环以获取所有指针B并将它们放入C中。当我退出程序时,我首先释放ListA,然后依赖取消分配ListA他们自己的指针B向量然后我释放指针C,但程序崩溃。

我已经调试了一下,并且知道解除分配时指针C指向什么,所以它不知道要解除分配的内容。

我做错了吗?或者我的问题的解决方案是什么?

抱歉,我会把我的代码放在

之下
//Class A
#pragma once

#include "MyContainer.h"
class B;
class A
{
public:
    A();
    ~A();
    MyContainer<B> *pListOfB;
}

A::A()
{
    pListOfB = new MyContainer<B>;
}
A::~A()
{
    if(pListOfB)
    {
        delete pListOfB;
        pListOfB = NULL;
    }
}
//Class C
#pragma once

#include "MyContainer.h"
class B;
class C
{
public:
    C();
    ~C();
    MyContainer<B> *pListOfB;
    void getListOfB(MyContainer<A> *pListOfA);
}

C::C()
{
    pListOfB = new MyContainer<B>;
}
C::~C()
{
    if(pListOfB)
    {
        delete pListOfB;
        pListOfB = NULL;
    }
}
void C::getListOfB(MyContainer<A> *pListOfA)
{
    for(pListOfA->isBegin(); !pListOfA->isEnd();)
    {
        A *pA = pListOfA->getNext();
        for(pA->isBegin(); !pA->isEnd();)
        {
            B* pB = pA->*pListOfB->getNext();
            pListOfB->add(pB);
        }
    }
}
//Class MyContainer
#pragma once

#include <vector>

template <class T> 
class MyContainer
{
public:
    MyContainer(void);
    ~MyContainer(void);
    T* getNext();
    void removeAll();
    void add(T* t);
    void isBegin();
    bool isEnd();   
private:
    std::vector<T*> items;  
    typename std::vector<T*>::iterator it;
};

template <class T> MyContainer<T>::~MyContainer()
{
    removeAll();
}

template <class T> void MyContainer<T>::add(T *t)
{
    items.push_back(t);
}

template <class T> void MyContainer<T>::removeAll()
{
    while(!isEmpty())
    {
        std::vector<T*>::iterator tempIt =items.begin();
        T* t = (*tempIt);
        items.erase(tempIt);
        delete t;
        t=NULL;
    }
}

template <class T>
T* MyContainer<T>::getNext()
{
    if(isEnd() || isEmpty())
        return NULL;    
    return (T*)(*(it++));
}

template <class T>
void MyContainer<T>::isBegin()
{
    it = items.begin();
}

template <class T>
bool MyContainer<T>::isEnd()
{
    return it==items.end();
}

我执行以下操作: 1.初始化列表对象:MyContainer * pListOfA; 2.将B数据插入pListOfA中的每个A对象 3.初始C对象 4.调用C对象操作getListOfB从pListOfA获取B数据。 5.退出程序

首先编程dealloc pListOfA,然后每个A释放它们自己的pListOfB。在该程序之后,dealloc C对象依次为C的dealloc pListOfB属性。但是pListOfB指向空,因为pListOfA释放每个数据。所以我的程序崩溃了。 我通过rem修复了在C类的dtor中删除pListOfB的行,但是我在那一行得到了一个警告内存泄漏。 这都是我的问题。请告诉我正确的方法。提前谢谢。

2 个答案:

答案 0 :(得分:0)

  • 首先,你分配
  • 然后你“拿走并放置”某处(不分配,只是复制指针)
  • 然后你解除分配
  • 然后你解除分配。 ...等待

答案 1 :(得分:0)

正确的方法是不使用普通指针

当你开始编写delete pointer;时,你必须重新考虑是否真的需要那个指针,如果你确实需要它,如果没有一些预先打包的智能指针类可以承担来自你的记忆管理。

您发布的示例代码可以完全编写而无需使用指针:

//Class A
#pragma once

#include "MyContainer.h"
#include "B.h"

class A
{
public:
    A() { };
    ~A() { };
    MyContainer<B> ListOfB;
};

//Class C
#pragma once

#include "MyContainer.h"
#include "B.h"

class C
{
public:
    C() { };
    ~C() { };
    MyContainer<B> ListOfB;
    void getListOfB(MyContainer<A>& ListOfA);
};

void C::getListOfB(MyContainer<A>& ListOfA)
{
    for(ListOfA.isBegin(); !ListOfA.isEnd();)
    {
        A& anA = ListOfA.getNext();
        for(anA.ListOfB.isBegin(); !anA.ListOfB.isEnd();)
        {
            B aB = anA.ListOfB.getNext();
            ListOfB.add(aB);
        }
    }
}

//Class MyContainer
#pragma once

#include <vector>

template <class T> 
class MyContainer
{
public:
    MyContainer(void);
    ~MyContainer(void) { };
    T& getNext();
    void removeAll();
    void add(const T& t);
    void isBegin();
    bool isEnd();   
private:
    std::vector<T> items;  
    typename std::vector<T>::iterator it;
};

template <class T> void MyContainer<T>::add(const T& t)
{
    items.push_back(t);
}

template <class T> void MyContainer<T>::removeAll()
{
    items.clear();
}

template <class T>
T& MyContainer<T>::getNext()
{
    if(isEnd() || isEmpty())
        return throw std::out_of_range("");
    return *it++;
}

template <class T>
void MyContainer<T>::isBegin()
{
    it = items.begin();
}

template <class T>
bool MyContainer<T>::isEnd()
{
    return it==items.end();
}

如果需要在A类和C类之间共享B实例(A和C中的列表都指向相同的B对象),那么您可以将shared pointers存储在列表中。