Problem mit doppeltem Zeiger?!



  • 🙂

    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.


Anmelden zum Antworten