PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++: Kann ich dyn. Arrays von dyn. Pointer Array (2 dimensional) löschen?


Vertex
2007-08-31, 00:09:18
C++: Kann/darf/muss ich dyn. Arrays, welche ihren Ursprung in einem dyn. Pointer Array haben (also dyn. 2 dimensional), löschen?

Ein Beispiel:

int count=10;
char **pArr;
pArr=new char*[count];
for (int i=0;i<count;i++)
{
pArr[i] = new char[sizeof("3dc")];
_tcsncpy_s(pArr[i] ,sizeof("3dc"),"3dc",sizeof("3dc"));
}
Wie lösche ich nun dieses 2 dimensionale Array. Einfach nur delete[] pArr;kommt mir irgendwie zu leicht vor. Sammelt das Programm da wirklich alle "new" Informationen über mehrere Dimensionen oder muss ich mir doch Sorgen machen?

Edit: mir gehts hauptsächlich darum, dass alles weg ist, wird also nur vom Destruktor aufgerufen.

Coda
2007-08-31, 01:00:50
Nein. Einfache Grundregel: Für jedes new/new[] ein delete/delete[], also wieder mit Schleife löschen. Auch aufpassen, dass Daten die mit new[] alloziert worden sind mit delete[] gelöscht werden und nicht mit delete.

Tipp: Lad dir von http://www.paulnettle.com/ unter Code den MMGR runter. Der zeigt dir im Debugmodus an wo du was leakst und ob du sonstigen Unsinn mit dem Speicher machst. Sehr sehr praktisch.

Besserer Tipp: std::vector und boost::multi_array verwenden.

Neomi
2007-08-31, 01:09:40
for (int i = 0; i < count; ++i)
delete[] pArr;

delete[] pArr;

Natürlich muß count für das Array noch stimmen, sonst hast du ein Speicherleck oder eine Zugriffsverletzung, je nach dem ob du zu wenig oder zu viel freigibst.

Edit:
Aaaaargh, böse Falle entdeckt: [i]sizeof("3dc") ist nicht die Länge des Textes (für die terminierende '\0' bräuchtest du eh noch ein Zeichen mehr), sondern die Größe eines char*.

sizeof("3dc") == sizeof("viel längerer Text, aber gleicher Typ")

Coda
2007-08-31, 01:17:04
In C++ ist sizeof("3dc") in der Tat 3 und damit die Länge des Textes Neomi. Das funktioniert nur nicht bei einem Pointer auf einen String.

Neomi
2007-08-31, 01:56:47
OK, wieder was gelernt. Meiner Meinung nach aber trotzdem eine unsinnige Erweiterung.

Vertex
2007-08-31, 07:13:11
In C++ ist sizeof("3dc") in der Tat 3 und damit die Länge des Textes Neomi. Das funktioniert nur nicht bei einem Pointer auf einen String.
Vielen Dank Coda, count ist zuverlässig valid (befinde mich innerhalb meiner Klasse).

soll das heißen wenn ich anstatt dem String "3dc" (hab gerade noch ein "Hallo" ausgebessert, sollte eigentlich auch 3dc heißen) einen Pointer auf einen String verwende ich Probleme bekomme?
also ungefähr so:

int count=10;
char **pArr;
pArr=new char*[count];
for (int i=0;i<count;i++)
{
pArr[i] = new char[sizeof(sArr(i))];
_tcsncpy_s(pArr[i] ,sizeof(sArr(i)),sArr(i),sizeof(sArr(i)));
}Wobei sArr(i) nichts anderes als einen dynamisch erstellten String darstellt.

Hatte schon ausprobiert dies mit einer for Schleife und dann einzeln delte[] auf sArr[i] zu machen... was zu einem mem leak führte...

MuLuNGuS
2007-08-31, 10:38:22
hä?

mit dieser zeile "pArr=new char*[count];" erzeugst du doch einen zeiger auf einen char, was bedeutet das es sich bei pArr um einen zeiger auf einen zeiger vom typ char handeln muß, so compiliert das ja mal nicht.

sollte dann wohl so aussehen: (falls nur ein typo auch egal)


char **pArr; //<- zeiger auf einen zeiger vom typ char
pArr=new char*[count]; //<- gibt einen zeiger vom typ char zurück

Coda
2007-08-31, 14:23:53
soll das heißen wenn ich anstatt dem String "3dc" (hab gerade noch ein "Hallo" ausgebessert, sollte eigentlich auch 3dc heißen) einen Pointer auf einen String verwende ich Probleme bekomme?
Ja, du brauchst strlen. sizeof(char*) ist immer 4 auf einer 32-Bit-Architektur.

Vertex
2007-08-31, 16:55:16
hä?

mit dieser zeile "pArr=new char*[count];" erzeugst du doch einen zeiger auf einen char, was bedeutet das es sich bei pArr um einen zeiger auf einen zeiger vom typ char handeln muß, so compiliert das ja mal nicht.

sollte dann wohl so aussehen: (falls nur ein typo auch egal)

char **pArr; //<- zeiger auf einen zeiger vom typ char
pArr=new char*[count]; //<- gibt einen zeiger vom typ char zurück
ja, sorry hatte in meinem ursprünglichen Code die beiden Sternchen an verschiedenen Stellen... also char* *pArrund habs deshalb nicht gesehen... gehört natürlich so... schon ausgebessert ;)

Ja, du brauchst strlen. sizeof(char*) ist immer 4 auf einer 32-Bit-Architektur.
also dann müsste es folgendermaßen aussehen:


int count=10;
char **pArr;
pArr=new char*[count];
for (int i=0;i<count;i++)
{
pArr[i] = new char[strlen(sArr(i))];
strncpy(pArr[i] ,strlen(sArr(i)),sArr(i),strlen(sArr(i)));
}und dann das delete dazu? müsste dann mit der for Schleife funktionieren... ok, langsam wird mir auch klar, warum ich beim "korrekten" Code mem leaks bekam...

Vertex
2007-08-31, 17:27:47
hab das jetzt mal probiert, aber komme da nicht wirklcih weiter.

for (int=0;i<count;i++)
{
delete[] (pArr[i]);
}
Dieser Code will einfach nicht funzen. :(

ich erzeuge das die Strings nun auch so:int count=10;
TCHAR* *pArr;
pArr=new THCAR*[count];
for (int i=0;i<count;i++)
{
pArr[i] = new char[tcslen(sArr(i))];
_tcsncpy_s(pArr[i] ,tcslen(sArr(i)),sArr(i),tcslen(sArr(i)));
}allerdings mit dem Unerschied, dass ich TCHAR verwende bzw. halt _tcslen (hab das jetzt auch mal so ausgebessert.

Irgendwie müsste das ja schon längst funktionieren oder?

del_4901
2007-08-31, 17:30:53
Nimm einfach std::string, und nicht diesen Scheiss, willst du C oder C++ programmiern? Du musst dich entscheiden!

Habe ich schonmal gesagt das ich C/C++ Mischcode hasse?

Und wo wir gleich dabei sind C++ zu lernen, kannst du auch gleich dazu noch std::vector nehmen.

Vertex
2007-08-31, 17:38:03
Nimm einfach std::string, und nicht diesen Scheiss, willst du C oder C++ programmiern? Du musst dich entscheiden!

Habe ich schonmal gesagt das ich C/C++ Mischcode hasse?Gut, mag sein, dass ich mische... sry for that... kann sein dass ich da zu stark eingerostet bin... trotzdem würde ich es gerne auf diese Art und Weise lösen, um zu sehen wie es funktioniert... es kann ja nicht sein dass ich meinen Speicher nicht wieder sauber frei bekomme.

Außerdem muss ich mit dem Format TCHAR auskommen und kann nicht die wunderschöne Stringklasse verwenden... Ich muss sozusagend TCHAR verwenden... Formatbedingt, da es sich um eine Konvertierung handelt.
Und wo wir gleich dabei sind C++ zu lernen, kannst du auch gleich std::vector nehmen.Wäre prinzipiell kein Problem, aber wie schon erwähnt würde ich es lieber so lösen um meine Kenntnisse in dieser Richtung etwas zu verbessern.

del_4901
2007-08-31, 17:43:37
Gut, mag sein, dass ich mische... sry for that... kann sein dass ich da zu stark eingerostet bin... trotzdem würde ich es gerne auf diese Art und Weise lösen, um zu sehen wie es funktioniert... es kann ja nicht sein dass ich meinen Speicher nicht wieder sauber frei bekomme.

Außerdem muss ich mit dem Format TCHAR auskommen und kann nicht die wunderschöne Stringklasse verwenden... Ich muss sozusagend TCHAR verwenden... Formatbedingt, da es sich um eine Konvertierung handelt.
Wäre prinzipiell kein Problem, aber wie schon erwähnt würde ich es lieber so lösen um meine Kenntnisse in dieser Richtung etwas zu verbessern.

Bist du sicher das die Konvertierung nicht hier irgendwo dabei ist:
http://msdn2.microsoft.com/en-us/library/87zae4a3(VS.80).aspx ?

Vertex
2007-08-31, 17:51:42
Bist du sicher das die Konvertierung nicht hier irgendwo dabei ist:
http://msdn2.microsoft.com/en-us/library/87zae4a3(VS.80).aspx ?Sorry, da hab ich mich wohl falsch ausgedrückt es geht nicht direkt um die Konvertierung von Strings selber, sonder um Konvertierung von Files, welche TCHAR Strings beinhalten... also auslesen, eventuell auswerten, schreiben... von TCHAR String zu TCHAR String... mhm... wobei mir gerade kommt... eigentlich könnte ich ja wirklich auf den Zieldatentyp TCHAR verzichten und dann doch alles in eine CString reinhauen...

mhm... du bist mir einen Schritt voraus ;), jetzt kann ich den Link doch recht gut gebrauchen ;D THX Stellt sich mir nur die Frage ob die Konvertierung so leicht hinhaut...
edit: bzw. ich nimm einfach CStringT dann erspar ich mir die Konvertierung und eventuell switche ich noch auf vector um... mal schauen

del_4901
2007-08-31, 18:01:07
edit: bzw. ich nimm einfach CStringT dann erspar ich mir die Konvertierung und eventuell switche ich noch auf vector um... mal schauen

Wenn du in dem Array noch suchen musst, nimm lieber was anderes. map / tree / set / k.A.

Vertex
2007-08-31, 18:02:39
Wenn du in dem Array noch suchen musst, nimm lieber was anderes. map / tree / set / k.A.nö muss ich zum Glück nicht... vielen Dank für deine Hilfe, hast mir sehr viel weitergeholfen... jetzt schau ich mal ob ich es so hinbekomme...

Coda
2007-08-31, 18:31:49
Noch besserer Tipp: Kein MFC benutzen. Kommt ganz ganz tief aus der Hölle.

Vertex
2007-08-31, 18:35:19
Noch besserer Tipp: Kein MFC benutzen. Kommt ganz ganz tief aus der Hölle.ebenfalls Anforderung, da ich mich mit MFC "leider" anfreunden muss/will... und bisher so gut wie gar nichts damit gemacht habe... deshalb hab ich auch noch einige Schwierigkeiten...

Danke für dein Beileid :wink:

Coda
2007-08-31, 18:37:52
Die Anführungszeichen bei leider kannst du weglassen.

del_4901
2007-08-31, 19:00:41
Noch besserer Tipp: Kein MFC benutzen. Kommt ganz ganz tief aus der Hölle.

Gibt es eigendlich diese lustige functor Union noch?

Bestimmt, Luzi ist doch faul wie sau.

Coda
2007-08-31, 20:35:01
Ich weiß nicht von was du redest :|
MFC wird soweit ich weiß nicht mehr wirklich weiterentwickelt und ich hab auch nicht vor es doch noch anfassen zu müssen.

del_4901
2007-08-31, 20:45:02
Ich weiß nicht von was du redest :|
MFC wird soweit ich weiß nicht mehr wirklich weiterentwickelt und ich hab auch nicht vor es doch noch anfassen zu müssen.

Irgendjemand kahm auf die glorreiche Idee eine Riesen-Union zu machen wo man alle MFC relevanten Functortypen reingepackt hat. Um "besser" zwischen den Typen "casten" zu können.

union MessageMapFunctions; <afximpl.h>

Coda
2007-08-31, 23:28:36
Super Idee! :ugly: