簡體   English   中英

刪除地圖中的指針<int,A*>

[英]Delete pointer in a map<int,A*>

基本上,B是一個對象,而A是一個對象管理器,對於創建的每個對象,將在m_myMap中執行一個新條目,以便跟蹤對象的數量並能夠獲取該對象的指針。

我的問題是:我必須在A的析構函數中的m_myMap中刪除B的指針,還是如果m_myMap被自動銷毀,將不會發生內存泄漏?

啊:

#ifndef A_H
#define A_H

#include "B.h"

class B;
class A
{
    public:
        A();
        ~A();
        int addB(B* myBPointer);
    private:
        std::map<int,B*> m_myMap;
}

#endif

BH:

#ifndef B_H
#define B_H

#include "A.h"

class A;
class B
{
    public:
        B(A* givenA);
        ~B();
    private:
        A *m_myA;
        int m_id;
}

#enfif

B.cpp:

B::B(A* givenA)
{
    m_myA = givenA;
    m_id = m_myA->addB(this);
}
B::~B(){} // nothing here because m_myA is coming from another class and is destroyed in that class

A.cpp:

A::A();

A::~A()
{
    for(std::map<int,B*>::iterator it = m_myMap.begin();it != m_myMap.end();++it)
        delete it->second;// the program crashes
}

int A::addB(B* myBPointer)
{
    m_myMap.insert(std::pair<int,B*>(m_myMap.size(),myBPointer));
    return m_myMap.size()-1;
}

C.cpp和Ch:

#ifndef C_H
#define C_H

#include "A.h"
class C
{
    public:
        C();
        void myFunction();
    private:
        A* my_A;
}

#endif

C::C()
{
    my_A = new A;
}

void C::myFunction()
{
    B myObject(my_A);
}

一個問題是:

m_myMap->erase(it);

無效it ,所以你不能安全地以后使用它。 通常,要在遍歷容器時擦除元素,請將循環結構如下

for (auto it = map.begin(); it != map.end(); /* don't increment here*/) {
    delete it->second;
    it = map.erase(it);  // update here
}

在這種情況下,由於您還是要銷毀地圖,因此無需刪除每個元素,只需刪除它們指向的對象即可。

您也沒有遵循“三個規則” ,因此您可能會意外地復制這些對象,最終導致兩個試圖刪除同一對象。 絕對沒有理由動態分配地圖,因此將其替換為對象成員

std::map<int,B*> map;

仍然存在的問題是,復制此副本會得到兩個帶有指向相同B對象的指針的映射。 如果沒有充分的理由進行動態分配,則將對象本身存儲在地圖中:

std::map<int,B> map;

如果確實需要動態分配(也許因為B是基類,並且實際對象可能是各種派生類型),則可以使用智能指針( std::unique_ptr可能是合適的),或者非常小心處理原始指針。

通常,除非確實需要,否則不要使用指針或new

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM