Mysteriöse Arrayentleerung

UncleBob

Mitglied
Bei mir scheint sich der Inhalt eines Arrays buchstäblich in Luft aufzulösen, in der folgenden Funktion. Sie ist ein member der Klasse ES_Cluster und soll dazu dienen spezifische Daten aus sich selbst an ein anderes Objekt desselben Typs weiterzugeben.

Code:
void ES_Cluster::CreateCube(ES_Cluster &Cube, long X, long Y, long Z)
{

	ES_Cluster TempCube;
	TempCube.Stars = new ES_Star[nStars];    //ein temporäres Objekt in das die Daten vorübergehend verschoben werden

	long StarCount = 0;
	size_t size;

	for (long count = 0; count < nStars; ++count)   //hier wird durch das ganze Objekt durchgegangen
	{
		if (Stars[count].CubeX == X && Stars[count].CubeY == Y && Stars[count].CubeZ == Z)      //prüfen ob die einzelnen objekte im Array Stars die Bedingungen erfüllen um weitergegeben zu werden 
		{
			TempCube.Stars[count] = Stars[count];
			++StarCount; //hier wird gezählt wie viele Objekte den Bedingungen entsprechen
		}
	}
//bis hierher läuft alles normal, TempCube enthält alle Daten die es weitergeben  soll

	Cube.Stars = new ES_Star[StarCount];   //Das Ausgabeobjekt wird auf die richtige Grösse getrimmt
	Cube.nStars = StarCount;

	for (long count = 0; count < StarCount; ++count)
	{
			Cube.Stars[count] = TempCube.Stars[count]; //und hier sollten dann die Daten an zur definitiven Verwendung weitergegeben werden. Nur: TempCube.Stars ist plötzlich leer. 
	}

}


Anzumerken ist dass TempCube.Stars nicht vollständig leer ist. Das Objekt [0] ist noch vorhanden, aber die restlichen Objekte sind alle Identisch, initialisiert zwar, aber mit Daten die weiss Gott woher kommen.Kann mir jemand sagen wo die ursprünglichen Daten hin sind?
 
Zuletzt bearbeitet:
Hi,

Kannst du bitte mal prüfen wie TempCube direkt beim Einstieg in die letzte Schleife aussieht?

Also ist da auch schon alles weg oder erst nach dem die Schleife betreten wird?

Setzte mal nen Debug-Punkt nach jeder anweisung und Prüfe ab wann die Daten futsch sind.

Gruß
Anfänger
 
Duh!

Jetzt bin ich dem Ding 2 Stunden hinterhergejagt, und jetzt, nachdem ich das Problem gepostet habe, habe ich den Fehler gefunden...

Eigentlich ist er ja mal wieder sehr offensichtlich: Es geht überhaupt nichts verloren. aber dank der Zeile

TempCube.Stars[count] = Stars[count];

haben die an TempCube übergebenen Objekte natürlich denselben Index wie in Stars, was heisst das alle dazwischenliegenden leer sind. Die zeile muss so aussehen:

TempCube.Stars[StarCount] = Stars[count];

und jetzt funktioniert die Sache auch problemlos. Sorry für die Verwirrung, und danke fürs ansehen. Bin tatsächlich beim genauen prüfen wo die Daten abhanden kommen darauf gestossen. :)
 
Also der Code scheint auf dem ersten Blick keinen groben Fehler zu haben.


Mir ist aber folgendes Inhaltlich aufgefallen:

Code:
if (Stars[count].CubeX == X && Stars[count].CubeY == Y && Stars[count].CubeZ == Z)
		{
			TempCube.Stars[count] = Stars[count]; //Diese Zeile :D
			++StarCount;
		}

sollte es vieleicht wie folgt lauten?
TempCube.Stars[StarCount] = Stars[count];


dann sonst werden ja die falschen Sterne angesprochen in der "Fehlerhaftenschleife

mfg
Gene
 
Hmm hab schon länger nix programmiert: Aber gib ma bitte Begründung warum du erst temp. Kopie erzeugst ... gibt da meines erachtens nur wenige Gründe für ;)

C++:
void ES_Cluster::CreateCube(ES_Cluster& cube, const long x, const long y, const long z)
{
	// Array von Zeigern auf die ES_Stars anlegen (und Iterator auf 1. Element)
	ES_Star** ptr_match = new ES_Star*[nStars]; 
	ES_Star** ptr_current = ptr_match;     

	// Zeiger auf den Stars-Array (Anfang und Ende zum iterieren)
	ES_Star* ptr_begin(&Stars[0]);
	ES_Star* ptr_end(ptr_begin + nStars);	       

	// Alle Stars durchlaufen
	for (ES_Star* ptr_it = ptr_begin; ptr_it != ptr_end; ++ptr_it)
		// Bedingung prüfen
		if (ptr_it->CubeX == x && ptr_it->CubeY == y && ptr_it->CubeZ == z)      
			// Zeiger auf Star speichern
			*ptr_current++ = ptr_it;

	// ptr_current zeigt auf Element hinter dem zuletzt belegten, u. ptr_match auf Anfang, Differenz ist Anzahl der (belegten) Elemente 
  	Cube.nStars = (ptr_current - ptr_match);
 	Cube.Stars = new ES_Star[Cube.nStars];

	// Zeiger auf das Zielarray anlegen (zum iterieren)
 	ptr_begin = &Cube.Stars[0];
	// Alle Zeiger auf passende Elemente durchgehen u. Objekt in Zielarray kopieren
 	for (ES_Star** ptr_it = ptr_match; ptr_it != ptr_current; ++ptr_it)
 	 	*ptr_begin++ = **ptr_it;
 	
	// Zeigerarray wieder freigeben ;)
	delete [] ptr_match;
}
Hm dadurch solltet du dir die ganzen Indexberechnungen sparen ... schonmal sehr viel schneller. Dann sollte so keine Kopie des Objektes sondern nur ein Zeiger auf einen Zeiger auf das Objekt kopiert werden und erst zum Schluss dann nur die wirklich zu kopierenden Objekte kopiert werden. Kann sein das nen Syntax-Fehler oder so drin ist ... hab keine IDE im Moment drauf ;)
 
Zuletzt bearbeitet:
Zurück