2010-08-24 62 views
2

我對Qt沒有太多經驗,但不知何故,我認爲這很奇怪。 編譯與VS2005:QList表演奇怪

class Entry 
{ 
public: 
    Entry(const QString& aName, bool checked) : 
     name(aName), isChecked(checked) 
    { 
     // empty 
    }; 

    Entry(const Entry& entry) : 
     name(entry.name), isChecked(entry.isChecked) 
    { 
     // empty 
    }; 

    Entry& operator=(const Entry& entry) 
    { 
     name = entry.name; 
     isChecked = entry.isChecked; 
     return *this; 
    } 

    QString name; 
    bool isChecked; 
}; 

typedef QList<conduit::Entry> EntryVector; 

當使用EntryVector在以下線,QList作的條目變成一個壞的指針:

void EntryWidget::setEntries(QStringList& names) 
{ 
    QStringList::iterator member; 
    EntryVector list; 

    for (member = names.begin(); member != names.end(); ++member) 
    { 
     Entry entry(*member, false); 
     list.append(entry); 
    } 

    m_model.setEntryData(list); 
} 

不知何故,entry.name在列表中會成爲一個壞的指針。我的理解是,QList應該能夠支持其模板中的任何數據,但由於某種原因,我還不明白這是行不通的。如果我使用STL向量,一切正常。

任何想法?由於

+0

「不知何故,列表中的entry.name將成爲一個錯誤的指針。」 這是什麼意思?因爲你不使用指針,我不明白這是怎麼發生的。 你可以顯示訪問列表的代碼嗎? – 2010-08-24 21:33:53

回答

1

我有同樣的問題,並尋找安澤。

我雖然我的代碼是行爲不端,當不是。

VS2005調試器沒有正確顯示你在QList中的東西。

而且正如davmac所建議的那樣,當你打印出來的東西時,它可以正常工作。

和davmac,請不要指出,當他給你一段代碼嘗試時,他可能會有內存損壞。如果你不能用相同的設置嘗試它,那是另一回事。

+0

海報並沒有說任何關於使用VS2005調試器的信息;他只是說'QList中的條目變成了一個糟糕的指針',好像這是除了調試器顯示的事實之外的事實陳述。我也不是唯一一個被這個困惑的人,請參閱Freank Osterfeld的評論。 – davmac 2013-04-24 14:15:34

+0

他說他已經用VS2005編譯過了。我認爲這是一個公平的假設,他正在使用VS2005調試器。我知道一個事實,即VS2005調試器不知道如何顯示一些Qt容器的內存。它所說的是「壞指針」。 – 0xbaadf00d 2013-05-14 07:49:27

+0

當然,但我沒有使用VS2005調試器,問題確實會說「使用VS2005編譯」,但沒有提及使用調試器的任何信息。對我而言,「壞指針」意味着腐敗,最可能的原因似乎是這堆堆在其他地方被損壞。發佈的代碼顯然沒有問題,所以我是否可以使用VS2005進行嘗試,或者似乎並不相關,除非它是我認爲不太可能的VS2005錯誤。如果問題更加明確,那麼我可以給出更好的答案。 – davmac 2013-05-14 12:33:53

0

「entry.name」不是指針 - 它宣佈與QString,在這裏:

public: QString name; 

那麼,你是什麼意思「entry.name將成爲一個壞的指針」?

很可能,程序的某些其他部分導致內存損壞。

+0

BadPtr是VS調試器在通過setEntries方法進行調試時顯示的內容。沒有其他線程處於活動狀態,因此,只要將條目添加到列表中,並且在調用了複製構造函數後,列表就不再包含該名稱的有效條目,我就沒有看到任何理由。只要'list.append(entry);'就會發生這種情況叫做。 QList中複製的條目只是丟失了名稱QString。 – 2010-08-25 13:46:16

+1

我從來沒有使用VS調試器,但是:我懷疑它不是entry.name,它是不好的指針,而是入口本身,因爲它已經超出了作用域(它在作用域的開始處,並且在循環結束時超出範圍;循環的迭代之間有一個簡短的時間點,它可以說是超出了範圍)。 嘗試更傳統的調試方法 - 在每次添加條目後,將列表內容打印到控制檯。我相信你會看到正在添加的條目,並且QList中的條目不會丟失名稱。 – davmac 2010-08-31 12:58:11

0

我假設,QStringList在其copy-ctor中創建了字符串的深度副本。

而且我們知道QList沒有深度複製。 see QListimplicit sharing

因此,在

void EntryWidget::setEntries(QStringList& names) {...} 

字符串中通話將被複制。

但是當你設置新進入 - 列出該模型,

m_model.setEntryData(list); 

列表不被複制到mmodel.xy

現在您可以訪問mmodel.xy,但你在setEntries(..)已經刪除指定的字符串。 他們失去了他們的範圍,當你離開setEntries(..)方法。

注意: QString是一個指向字符串的引用指針。這被稱爲「隱式共享」。 Qt中的所有容器都有懶惰評估的概念。 (也許除了QStringList中,這使得深度拷貝。這也許是Qt的一個小錯誤,我可以只說100%,如果我看到的.cpp)

qt-project.org/doc /qt-5/qstringlist.html#QStringList-3