指针的释放

发布于 2024-10-01 08:02:12 字数 2734 浏览 0 评论 0原文

我有一个 A 类型的列表指针(称为 ListA),容器是指针 B 的向量。(每个 A 对象都是一个具有私有属性的容器类:std*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. 初始化一个列表A对象:MyContainer *pListOfA; 2.将B数据插入到pListOfA中的每个A对象中 3. 初始C对象 4. 调用C对象操作getListOfB从pListOfA中获取B数据。 5.退出程序

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

I have a list pointer in type of A (called ListA) container a vector of pointers B. (Each A object is a container class that has a private attribute: std<vector> *B). Then, I declare a pointer (called C having the same type as A), make a for-loop through ListA to get all pointers B and put them in C. When I quit my program, I deallocate ListA first, ListA in turn deallocates their own vector of pointers B. Then I deallocate pointer C, but the program crashes.

I have debugged this a bit and know that pointer C at the time of deallocation points to nothing, so it doesn't know what to deallocate.

Am I doing wrong? Or what is the solution for my problems?

Sorry, I'll put my code below

//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();
}

I do the following action:
1. Initial a list A object : MyContainer *pListOfA;
2. Insert B data to each A object in pListOfA
3. Initial C object
4. Call C object operation getListOfB to get B data from pListOfA.
5. Quit program

Program first dealloc pListOfA, each A then dealloc their own pListOfB. After that program dealloc C object in turn dealloc pListOfB attribute of C. But pListOfB point to nothing because pListOfA deallocs every data. So my program crash.
I fix by rem the line delete pListOfB in the dtor of class C but I got a warning memory leak at that line.
That's all my problem. Please show me the right way. Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

海的爱人是光 2024-10-08 08:02:12
  • 首先,您分配,
  • 然后您“取出并放置”某处(不分配,只是复制指针),
  • 然后您取消分配
  • ,然后您取消分配。 ...等待
  • first, you allocate
  • then you "take and put" somewhere (not allocating, just copying pointers)
  • then you deallocate
  • then you deallocate. ...wait
∝单色的世界 2024-10-08 08:02:12

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

当你开始编写deletepointer;时,你必须重新考虑是否真的需要该指针,如果确实需要它,是否没有一些预先打包的智能指针类可以接受内存管理的负担由您承担。

您发布的示例代码完全可以在不使用指针的情况下编写:

//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();
}

如果 B 实例需要在类 A 和类 C 之间共享(A 和 C 中的列表都引用相同的 B 对象),那么您可以存储 <列表中的 href="http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/shared_ptr.htm" rel="nofollow">共享指针。

The right way is not to use plain pointers.

The moment you start to write delete pointer;, you have to reconsider if you really need that pointer and if you do need it, if there is not some pre-packaged smart-pointer class that can take the burden of memory management from you.

The example code you posted can be written entirely without the use of pointers:

//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();
}

If the B instances need to be shared between class A and class C (the lists in A and C refer both to the same B objects), then you could store shared pointers in the lists.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文