2013-01-15 51 views
0

我似乎有一個奇怪的問題,但它可能是QMap的工作方式和我不明白它的一個怪癖。總結這個問題很難,但我會盡我所能。使QMap內部的指針值無效

我有一個類A,與QMap<QString, someType*> mySomeTypeMap;。當我在我的程序中加載一個新文件時,我想刪除此QMap的所有內容,以便我可以用新數據重新填充它。我這樣做,這樣做以下方式:

foreach (QString key, mySomeTypeMap.keys()) 
{ 
    someType* toDelete = mySomeTypeMap.take(key); 

    //Show me the original address of the pointer 
    qDebug() << "toDelete: " << toDelete; 

    delete toDelete; 

    //Set the pointer to 0x0 
    toDelete = NULL; 
} 

qDebug()語句打印出來我想要刪除,並且該值的正確地址,當我在之後它被設置爲NULL調試器看toDelete,它說爲0x0 ,這是我想要的。

再後來,在一個不同的類B,我有以下的代碼...

void B::setSomeType(someType* blah) 
{ 
    if (Blah != NULL) 
    { 
     //Calls a bunch of disconnect()'s 
     disconnectAllSignals(); 

     Blah = blah; 

     //Calls a bunch of connect()'s 
     connectAllSignals(); 
    } 
} 

現在,什麼是真正困惑我的程序崩潰,當它到達disconnectAllSignals();線。原因是它試圖呼叫disconnect()Blah已被刪除,並應設置爲0x0當我將其設置爲NULL。但是,如果它實際設置爲NULL,它永遠不會進入if-block開始。在調試器中,我看到Blah的地址與我在設置toDelete = NULL;之前打印出qDebug() << "toDelete: " << toDelete;時的地址完全相同。

TLDR;我不知道如何刪除指針並將指針設置爲NULL後,我的程序如何獲取指針的原始地址。由於指針在執行後期未設置爲NULL,因此導致崩潰。

+0

第一個猜測:你沒有關注三的** **規則爲'someType'。向我們展示'someTye'的定義。另外,'mySomeTypeMap.take(key)'返回原始元素或指向元素本身的指針的拷貝是什麼? –

+0

那麼,構造函數和析構函數都是空的......這是一個非常簡單的數據類,它不包含任何我需要清理的指針。我沒有明確實現複製構造函數。無論如何,這將如何引發問題?並回答你的第二個問題,http://doc.qt.digia.com/qt/qmap.html#take – roundtheworld

+0

'QMap :: take(..)'從地圖中刪除條目,那麼之後它是什麼意思?它不存在於地圖中,副本立即超出範圍。 – cmannett85

回答

3

即使在這種情況下它表示指針(它指向的地址)按值存儲,映射中的值仍按值存儲。 例如:

someType* toDelete1 = mySomeTypeMap.take(key); 
someType* toDelete2 = mySomeTypeMap.take(key); 
someType* toDelete3 = toDelete1; 
toDelete1 = NULL; 

toDelete2 & toDelete3仍將指向原始對象

不是使指針無效後刪除您應該從地圖上刪除它或將值設置爲關鍵NULL 。

2
someType* toDelete = mySomeTypeMap.take(key); 

這是在堆棧上創建的指針變量,其值設置爲您在映射中保留的值。你不需要將它設置爲NULL,因爲它馬上超出了範圍。

take函數正在從地圖中刪除指針,如果您再次使用同一個鍵,它將返回默認構造的值。只是delete後嘗試

mySomeTypeMap.insert(key, 0); 
+0

好吧,原始類型的「默認值」由Qt容器設置爲0,所以你不需要我回答中的最後一行。問題必須在別處。 – yattering