我用wxWidgets編寫了一個應用程序,它使用wxList。我在收集列表數據的析構函數中有一些隨機crahses(segfault)。我找不到從列表中刪除項目的明確方法(Erase()VS DeleteNode())。即使迭代項目有兩種風格(list-> GetFirst()VS list-> begin())。在wxWidgets中處理鏈表的正確方法是什麼?
下面是一個測試類,顯示我在我的應用程序中使用的方法。測試運行完美,沒有崩潰。似乎有些指針在被釋放後正在使用,但我無法通過查看代碼來判斷。我想我在做Erase()和DeleteContents()調用時會出錯。
P.S:在應用程序中,列表包含大約15000個項目,而測試中僅包含9個項目。
#include <wx/list.h>
#include <wx/log.h>
class TestItem
{
public:
TestItem(int _x, int _y) { x = _x; y = _y; }
int x;
int y;
};
WX_DECLARE_LIST(TestItem, TestList);
#include <wx/listimpl.cpp>
WX_DEFINE_LIST(TestList);
class Test {
public:
TestList *list;
Test() {
list = new TestList;
}
~Test() {
Clean();
delete list;
}
void CreateAndAddToList(int x, int y) {
TestItem *item = new TestItem(x, y);
list->Append(item);
}
void PrintAll() {
wxLogMessage(wxT("List size: %d"), list->GetCount());
wxTestListNode *node = list->GetFirst();
while (node) {
TestItem *item = node->GetData();
wxLogMessage(wxT("Item: %d, %d"), item->x, item->y);
node = node->GetNext();
}
}
void DeleteAllX(int x) {
wxTestListNode *node = list->GetFirst();
while (node) {
TestItem *item = node->GetData();
if (item->x != x) {
node = node->GetNext();
continue;
}
wxTestListNode *toDelete = node;
node = node->GetNext();
wxLogMessage(wxT("Deleting item: %d, %d"), item->x, item->y);
list->Erase(toDelete);
delete item;
}
}
void Clean() {
list->DeleteContents(true);
list->Clear();
}
static void DoAllTests() {
Test *t = new Test;
t->CreateAndAddToList(1, 1);
t->CreateAndAddToList(1, 2);
t->CreateAndAddToList(1, 3);
t->CreateAndAddToList(2, 1);
t->CreateAndAddToList(2, 2);
t->CreateAndAddToList(2, 3);
t->CreateAndAddToList(3, 1);
t->CreateAndAddToList(3, 2);
t->CreateAndAddToList(3, 3);
t->PrintAll();
t->DeleteAllX(2);
t->PrintAll();
t->Clean();
t->PrintAll();
delete t;
}
};
你可以避免頭痛和麻煩,並使用'std :: list'。已經由數百萬用戶進行編碼和測試。 – 2010-10-01 21:16:44
我沒有注意到wxList已被棄用的文檔。無論如何,新的API幾乎與std :: list相同。我改變了我的應用程序使用std :: list,一些錯誤似乎消失了。至少現在我有更多關於列表後端的文檔。 – streeto 2010-10-06 13:45:36