2017-12-20 7 views
25

Ich habe folgendes Problem:Array-Zeigerdaten werden zwischen Funktionsaufrufen ohne expliziten Befehl gelöscht?

In einem C++ Programm, das ich eine globale Datenstruktur als Renderer Rendering_Handler erklärt habe, die ein Mitglied Feld als vector<Render_Info> visble objects definiert enthält.

Was die Datenstrukturen selbst tun, ist nicht wichtig, sie sind Wrapper, die benötigt werden, um Daten zu abstrahieren, um mein Programm zu parallelisieren.

Um klar zu sein, Rendering_Handler ist vollständig global, und es ist in der Tat ein Singleton (ich kann 100% bestätigen, dass der Konstruktor einmal und nur einmal für diese Klasse aufgerufen wurde).

Ich habe die folgende Klasse Methode deklariert:

Render_Info* Renderer::add_Render_Info() 
{ 
    visible_objects.push_back(Render_Info()); 
    return &(visible_objects.back()); 
} 

Einfach genug, erstellt es eine neue Render_Info Struktur, fügt sie das visible_objects Array und gibt einen Zeiger auf das Objekt.

Eine andere Chunk genannt Datenstruktur hat einen Konstruktor definiert als

Chunk::Chunk(vec3 offset, World* w) 
{ 
    /*initialize some values*/ 

    draw_info = Rendering_Handler->add_Render_Info(); 
    draw_info->VBOs = vector<GLuint>(5); 

    /*initialize OpenGL VAOs, VBOs and other buffer objects*/ 

    cout << draw_info->VBOs.size() << endl; 
    cout << draw_info << endl; 
} 

Es wurde auch ein Verfahren wie folgt definiert:

void Chunk::update_render_info() 
{ 
    cout << draw_info->VBOs.size() << endl; 
    cout << draw_info << endl; 

    /*OpenGL stuff*/ 

} 

und das Verfahren schließlich

Wir haben das alles initialisiert :

World::World() 
{ 
    /*Initialize chunks in a circular 3D array*/ 
    loaded_chunks = new Chunk_Holder(h_radius, h_radius, v_radius, this); 

    for(int i=0; i<h_radius; i++) 
    { 
     for(int j=0; j<h_radius; j++) 
     { 
      for(int k=0; k<v_radius; k++) 
      { 
       (*loaded_chunks)(i,j,k)->update(); 
      } 
     } 
    } 
} 

Der Ausgang des rpgram ist:

enter image description here

...

enter image description here

Fokus Lassen Sie uns auf die frist 2 und letzten 2 Zeilen der Ausgabe, die dem Druck entsprechen Anweisungen, die ich zum Debuggen hinzugefügt habe.

Die ersten zwei Linien zeigen, dass 5-Elemente an den Puffer an der Stelle 0x556edb7ae200

Die letzten 2 Zeilen mir sagen, hinzugefügt wurden, dass der gleiche Puffer (gleiche, da der Speicherplatz das gleiche ist) 0 Elemente enthält jetzt.

Wie Sie anhand der Snaps des Codes sehen können, wird zwischen dem Erstellen und Aktualisieren der Chunks keine Funktion aufgerufen. Hat jemand eine Vorstellung davon, was das Verschwinden dieser Elemente verursachen könnte?

Habe ich den Speicher nicht richtig reserviert? Werden diese Objekte aufgrund einer falschen Zuordnung ohne mein Wissen gelöscht?

+16

'visible_objects.push_back()' Aufruf kann alle Zeiger auf Elemente von 'visible_objects' ungültig machen, wobei all Ihre 'draw_info'pointers hängen bleiben. –

+0

OHHHH schießen, meinst du, es wird den Speicher neu zuordnen, wenn es über die vorher zugewiesene Grenze hinausgeht, wodurch jeder einzelne Zeiger auf einen neuen Punkt verschoben wird? – Makogan

+0

Vorgegebene Codebits erzeugen überhaupt keine Ausgabe, und Sie reservieren auch keinen Speicher (der die Ungültigkeit des Zeigers verhindert). – VTT

Antwort

9

Ich denke, das Problem ist, dass Sie Zeiger auf Elemente in Vektor speichern und zur gleichen Zeit rufen Sie vector::push_back, die immer wieder die Größe des Vektors ändern und alle Elemente in neue Speicherblock verschieben müssen. Dies wird alle Zeiger ungültig machen, die Sie zuvor erhalten haben.

Um Ihnen mehr Kontext zu geben: vector speichert seine Elemente in einem kontinuierlichen Stück Speicher. Wenn vector::push_back aufgerufen wird und in diesem Speicherbereich kein freier Speicherplatz mehr vorhanden ist, wird vector einen weiteren Speicherbereich mit der doppelten Größe des alten Speicherbereichs zuweisen. Dann kopiert/verschiebt es alle Elemente vom alten Chunk zum neuen. Endlich wird der alte Brocken zerstört. Wenn Sie &(visible_objects.back()) aufrufen, erhalten Sie eine Adresse im Speicher, die sich innerhalb des aktuellen Speicherbereichs von visible_objects befindet. Wenn später visible_objects.push_back aufgerufen wird und visible_objects in einen neuen größeren Speicherbereich migrieren muss, werden alle zuvor erhaltenen Adressen veraltet sein, da sie auf den alten Speicherbereich zeigen, der zerstört wurde.

Verwandte Themen