2017-04-23 7 views
-2

Ich habe einen std :: Vektor von Strukturzeigern, in denen ich doppelte Einträge entfernen möchte. Ich möchte jedoch ein Element der Struktur anstelle des Zeigers direkt vergleichen. Wenn ich es auf die falsche Art mache (die Zeiger direkt vergleichen), gibt es keinen segfault; die Betrogenen werden einfach nicht entfernt. Wenn ich jedoch auf das fragliche Element zugreife, bekomme ich einen Segfault.C++ segfault im Zeigervergleich

Meine erste Vermutung wäre, dass die Strukturen ungültig/freigegeben sind, aber ich kann dieses Mitglied in ein Char-Array setzen und es direkt im Debug-Protokoll ohne ein Problem zu drucken, so scheint dies nicht der Fall zu sein.

Wenn die Strukturen gültig sind (was sie beide zu sein scheinen und sein sollten; ich calloc jeden vor dem Hinzufügen), dann weiß ich nicht, warum der Vergleich ihrer Mitglieder irgendein Problem verursachen würde.

Anyways, hier ist mein Code:

struct Definition:

81   struct fp_node{ 
82    Tile *t; 
83    unsigned int g; 
84    unsigned int h; 
85    unsigned int score; 
86    struct fp_node *parent; 
87    char type; 
88   }; 

Zugriff auf das Mitglied ohne Ausgabe

279 #ifdef DEBUG 
280   for(unsigned int i = 0; i < open_list.size(); ++i){ 
281    char address[11]; 
282    snprintf(address, 11, "0x%08x", open_list[i]->t); 
283    gui::log("Open list entry " + std::to_string(i) + ": " + std::string(address)); 
284   } 
285 #endif  

Betrogene Filterung das Problem verursacht:

291   for(unsigned int i = 0; i < open_list.size(); ++i){ 
292    for(unsigned int j = 0; j < open_list.size(); ++j){ 
293     if(i == j) continue; 
294     if(open_list[i]->t == open_list[j]->t){ 
295      free(open_list[j]); 
296      open_list.erase(open_list.begin() + j); 
297      i -= 1; 
298      j -= 1; 
299     } 
300    } 
301    
302    for(unsigned int j = 0; j < closed_list.size(); ++j){ 
303     if(open_list[i] != closed_list[j]) continue; 
304     free(open_list[i]); 
305     open_list.erase(open_list.begin() + i); 
306     i -= 1; 
307    } 
308   } 

Beachten Sie, dass ich in der ersten j for-Schleife auf das t-Mitglied der Struktur zugreife. Dies verursacht den Segfault. Die zweite Schleife vergleicht einfach die Zeiger. Es segfault nicht, aber es ist nicht was ich will.

Ich habe versucht, Methoden aus der Kachel-Klasse zugreifen, aber diese segfault auch, so denke ich, dass der Speicher irgendwie in der Zwischenzeit automatisch freigegeben wird. Ich weiß jedoch nicht warum, denn alles ist auf dem Haufen außer den Vektoren selbst, die in einem größeren Umfang sind und nicht sterben sollten.

Wenn ich jedoch versuche, nur in einem Teil des Vergleichs (if((Tile *)open_list[i] == open_list[j]->t)) auf das Element zuzugreifen, erhalte ich keinen segfault; Gleiches mit der anderen Seite.

Ich bin hier völlig verloren, kann mir bitte jemand helfen?

Danke.

+0

'fp_node' einen Zeiger enthält, aber nicht über die Werkzeuge, um den Zeiger zu verwalten. Dies macht es anfällig, dass zwei Kopien auf den gleichen Speicher zeigen. Keine Möglichkeit zu sagen, was gegeben wurde, um zu sagen, ob dies oder irgendetwas anderes das Problem ist. – user4581301

+1

Zu viele Möglichkeiten für die Ursache hier. Sie müssen ein [mcve] bereitstellen. Gewählt, um entsprechend zu schließen. Sie müssen wahrscheinlich überprüfen, ob die Zeiger im Vektor gültig sind, bevor Sie sie dereferenzieren (z. B. auf ihre Mitglieder zugreifen). – Peter

+0

@ user4581301 Das ist der Grund, warum ich das in erster Linie tun möchte. Dies ist das Werkzeug zum Verwalten des Zeigers. – Yapoz

Antwort

1

Ich hoffe, die schläfrig in meinen Augen macht mich nicht sehen Spots, aber etwas springt auf mich.

Schwer zu sagen, wie Sie nicht sagen, wie open_list zugeordnet ist. Da open_list von free() freigegeben wird, gehe ich davon aus, dass es sich um einen einfachen Zeiger handelt, der von malloc() oder calloc() zugewiesen wurde, und dies sind C-Funktionen. Habe nie versucht, malloc() und size() oder new() und free() zu mischen, aber ich befürchte, dass die von open_list.size() gemeldete Array-Größe sich unter free() nicht ändern würde.

Siehe http://www.cplusplus.com/reference/array/array/size/

+0

open_list ist auf dem Stapel. Die Strukturen im Inneren sind Calloced und Freigegeben. – Yapoz