Problem mit doppeltem Zeiger?!
-
Ok, wird nun wahrscheinlich eine doofe Frage sein, aber ich habe ein Problem, wenn ich einen doppelten Zeiger korrekt löschen (deleten) möchte:
Ich habe:
CDialog** pages;
Das initialisiere ich dann auch brav:
pages = new CDialog*; pages[0]=new CDialog; ....
Doch wie schreibe ich das delete korrekt hin
delete[] pages;// geht nicht! delete[] *pages; // auch nicht... :(
Komme leider nicht darauf.
Bin für Hilfe dankbar.
-
for(i=0;i<pagecount;++i) delete pages[i]; delete[]pages;
(übrigens würde ich den Bereich auch mit einem "pages=new (*CDialog)[pagecount];" reservieren)
Aber wozu benötigst du denn diese doppelte Verkettung?
Edit: Achja, immer die richtigen new/delete zusammenpacken - Was du mit "var=new T;" reserviert hast, wird mit "delete var;" freigegeben, zu "vat=new T[n];" gehört "delete[] var;" (und zu "var=malloc(n);" gehört "free(var);").
-
Danke, hat funktioniert.
Ich verstehe wohl nun auch, warum ich unbedingt
"pages=new (CDialog*)[pagecount];" schreiben muss.Ich benutze einen doppelten Zeiger, um eine variable Größe zu haben. Ich schreibe mir gerade eine Klasse zum Anzeigen von einem TabCtrl mit einer benutzerdefinierten Anzahl an Seiten.
Wollte zuerst nur einen Zeiger machen, da hat er aber gemeckert.
Vielen Dank.
MfG,
Paul.
-
Ok, hier noch ne Frage:
Ich habe einen Parameter:
UINT* test
Dieser bekommt ein Array übergeben:
UINT param[10];
Dieser Parameter wird natürlich gefüllt.
Da aber die Anzahl variable sein soll, möchte ich gerne vorher prüfen, wieviele Elemente es wirklich enthält. Die Frage ist nur, wie?
Habe es mit sizeof versucht, führte aber nicht zum Erfolg.Ich habe das Gefühl, dass ich mich irgendwie doof anstelle.
Wäre nett, wenn mir jemand eben auf die Sprünge helfen könnte.
MfG,
Paul.
-
musst du als zweiten Parameter mit übergeben. Aus dem Zeiger lässt sich die Anzahl nicht feststellen
-
Aus der MSDN hatte ich das hier:
static char *strings[] ={
"this is string one",
"this is string two",
"this is string three",
};
const int string_no = ( sizeof strings ) / ( sizeof strings[0] );Aber das gibt im Falle von UINT immer "4/4 = 1" wieder.
Dann geht das wohl wirklich nicht anders.
Danke.
-
Das hier ist auch ein feld, wo bei der Compilezeit die Größe bekannt ist.
-
? Das heißt nun?
Kann ich das nun doch lösen, wenn die Größe nun doch bekannt ist?...
Also, heute stehe ich glaube ich mit allen Händen und Füßen auf dem Schlauch...
-
Wenn das Feld dynamisch ist un bei der Laufzeit erst die Größe feststeht, musst du dir die Anzahl irgendwo merken und bei Funktionen mit übergeben.
Wenn du ein statisches feld machst, kann man auch die Größe so bestimmen.
-
Paul_C. schrieb:
Da aber die Anzahl variable sein soll, möchte ich gerne vorher prüfen, wieviele Elemente es wirklich enthält. Die Frage ist nur, wie?
Habe es mit sizeof versucht, führte aber nicht zum Erfolg.Sonst mach doch ein Endekennzeichen rein, so wie bei einem String. Einfach noch ein Element dran und das ist NULL.
-
Ok, danke für die Denkanstöße!
Hier mal nen Code-Schnipsel zum Verdeutlichen, was ich vorhabe:
UINT ids[6] = {IDD_DIALOG1, IDD_DIALOG2, IDD_DIALOG3, IDD_DIALOG4, IDD_DIALOG5, IDD_DIALOG6}; LPCTSTR names[6]= {"Options","Testing","Motor","Projects", "Settings", "Check"}; m_cTabCtrl.InitPages(6,ids,names);
So, das erste Array enthält die IDs der Dialoge, welche ich mit meiner TabCtrl Klasse anzeigen möchte.
names enthält die Namen der einzelnen Tabs.
InitPages() erzeugt das Control mit 6 "Pages", mit den folgenden IDs und Namen.Nun wollte ich bloß schauen, falls names nur vier Namen enthält, Default-Namen einsetzen. Das geht ja mit strlen(). EDIT: Geht doch nicht mit strlen(), -> war bloß Zufall.
/EDIT
Falls aber die Anzahl an Elementen von ids nicht 6 entspricht, dann will ich darauf auch entsprechend reagieren.Daher möchte ich die Anzahl der übergebenen Elemente herauslesen.
-
Idee:
UINT ids[6] = {IDD_DIALOG1, IDD_DIALOG2, IDD_DIALOG3, IDD_DIALOG4, 0, 0};
Schon sind nur 4 drin und du kannst ganz einfach danach abfragen.
LPCTSTR names[6]= {"Options","Testing","Motor","Projects", "", ""};
Was sagt strlen dazu?
-
Du kannst im Hauptprogramm die tatsächliche Größe deines Arrays berechnen (mit sizeof(array)/sizeof(array[0])) und als Parameter angeben - dort weiß der Compiler (noch), daß das ein Array ist und welche Größe es hat. In der Funktion kannst du nur noch mit Pointer-Arithmetik arbeiten, d.h. du benötigst eine explizite (als Parameter) oder implizite (Ende-Kennung) Angabe , wie groß dein Array ist.
d.h. du könntest so etwas machen:
UINT ids[6] = {IDD_DIALOG1, IDD_DIALOG2, IDD_DIALOG3, IDD_DIALOG4, IDD_DIALOG5, IDD_DIALOG6}; int id_count=sizeof ids/sizeof ids[0]; LPCTSTR names[]= {"Options","Testing","Motor","Projects", NULL}; m_cTabCtrl.InitPages(id_count,ids,names); //... InitPages(int count,UINT* ids,LPCTSTR* names) { bool def_name=false; for(int i=0;i<count;++i) { if(names[i]==NULL) def_name=true; CString pagename=def_name?"Default":names[i]; InitSinglePage(ids[i],pagename); } }
-
Ok, danke für eure Ideen!
Werde nun mal alles ausprobieren.@estartu_de: das mit strlen() sage ich dir dann, wenn ich es getestet habe.
-
estartu_de schrieb:
Sonst mach doch ein Endekennzeichen rein, so wie bei einem String. Einfach noch ein Element dran und das ist NULL.
Keine gute Idee, dann musst du ja jedesmal das Array komplett durchgehen, um die Anzahl zu ermitteln. Sich die Grösse seperat zu merken, ist da schon vernünftiger.
Paul_C. schrieb:
Aber das gibt im Falle von UINT immer "4/4 = 1" wieder.
Deshalb sollte man in C++ auch eine entsprechende Funktion benutzen, wo der Compiler bereits meckert, wenn man kein "echtes" Array hat.
template <class T, size_t N> size_t lengthof(const T(&)[N]) { return N; }
Sowas kann man übrigens auch verwenden, um Arrays zu übergeben, ohne dass deren Informationen verlorengehen.
-
Auch interessant, mit Templates arbeite ich normalerweise nie.
Werde mir das also nochmal alles durch den Kopf gehen lassen.Danke nochmal an euch alle.