Hilfe zu malloc, calloc und new!



  • Hallo Forum,
    ich könnte ein bißchen Hilfe bei diesen Funktionen brauchen 🙂
    es geht um das freigeben des mit malloc und calloc reservierten Speichers,
    irgendwie klappt das nicht!
    Und was ist jetzt der Unterschied zwischen malloc und wenn ich new benutze,
    hier mein Versuch:

    // ich möchte den Inhalt einer CString Variable in ein wchar_t kopieren, darf
    //auch ein TCHAR sein:
    wchar_t* acPath = (wchar_t*) malloc(csPath.GetLength() + 1);
    acPath = csPath;
    
    // jetzt das freigeben, schlägt immer fehl
    free(acPath); // hier Access Violation...
    // wenn ich acPath auf NULL setze dann gehts schon, ich weis aber nicht ob der 
    // reservierte Speicher auchfreigegeben wurde
    acPath = NULL;
    // und dann:
    free(acPath); // weis nur nicht ob das auch richtig ist??
    

    Wie muß das richtig gemacht werden, und ob dies eine Alternative ist:

    wchar_t* acPath = new wchar_t[csPath.GetLength() + 1];
    wcscpy(acPath, csPath.GetBuffer(csPath.GetLength()));
    // tue irgendwas mit acPath, z.B. suchen nach teilstrings
    BOOL bGefunden = SucheTeilString(acPath);
    // wenn zurück dann acPath freigeben:
    delete(acPath); 
    // dieses Modell funktioniert, aber ist es eine Alternative zu dem oberem!
    

    Sobald ich etwas in den allocierten Speicher kopiere, muß ich erst NULL
    zuweisen um ihn dan mit free(acPath); freigeben zu können!
    Wie verwendet man richtig malloc, calloc und realloc!
    Hab nichts gefunden in den faq's. 😞 😕
    In der MSDN ist zwar ein Beispiel dabei, aber ohne der neuen Variablen einen
    Wert zu zuweisen, so gehts bei mir auch, Problem ist wie gesagt, wenn ich einen
    Wert zugewiesen habe, und dann den Speicher fregeben möchte, weil ich ihn
    nicht mehr brauche, auch den Inhalt nicht!

    besten Dank
    pixel



  • malloc/free unterscheiden sich von new/delete hauptsächlich darin, daß letztere auch die Größe und Ctoren des verwendeten Datentyps berücksichtigen. Bei char's fällt dieser Unterschied nicht auf, aber bei größeren Typen mußt du darauf achten.

    pixel schrieb:

    Hallo Forum,
    ich könnte ein bißchen Hilfe bei diesen Funktionen brauchen 🙂
    es geht um das freigeben des mit malloc und calloc reservierten Speichers,
    irgendwie klappt das nicht!
    Und was ist jetzt der Unterschied zwischen malloc und wenn ich new benutze,
    hier mein Versuch:

    // ich möchte den Inhalt einer CString Variable in ein wchar_t kopieren, darf
    //auch ein TCHAR sein:
    wchar_t* acPath = (wchar_t*) malloc(csPath.GetLength() + 1);
    acPath = csPath;
    
    // jetzt das freigeben, schlägt immer fehl
    free(acPath); // hier Access Violation...
    // wenn ich acPath auf NULL setze dann gehts schon, ich weis aber nicht ob der 
    // reservierte Speicher auchfreigegeben wurde
    acPath = NULL;
    // und dann:
    free(acPath); // weis nur nicht ob das auch richtig ist??
    

    Erstens: malloc() gibst du die Größe in Byte an - und ein wchar_t ist etwas größer als ein Byte. Also mußt du den Speicher anfordern mit "wchar_t* acPath = (wchar_t*) malloc((csPath.GetLength() + 1)*sizef(wchar_t));".

    Zweitens: Durch die Zuordnung vergisst du die Adresse der mit malloc angelegten Speicherbereiches und biegst deinen Zeiger auf den internen Puffer von csPath (ergibt ein Speicherleck, weil du diesen Block nicht mehr wiederfindest UND eine Schutzverletzung, wenn du den von CString verwalteten Speicher freigeben willst). Richtig wäre an dieser Stelle ein wcscpy()-Aufruf wie in deinem new-Beispiel.

    Drittens: Erst free(p) aufrufen, dann auf NULL setzen. Umgekehrt macht es keinen Sinn.

    PS: Ich schieb's mal rüber zu C++, da das Problem nichts mit MFC zu tun hat.



  • Dieser Thread wurde von Moderator/in CStoll aus dem Forum MFC (Visual C++) in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Hi,

    noch ein paar Ergänzungen:

    pixel schrieb:

    ...

    ...
    acPath = csPath;
    ...
    

    ...

    Dass das nichtmal zu einer Warnung führt, kann ich mir kaum vorstellen. Was hat denn "csPath" für einen Typ (String ?) ? Hat der einen Konvertierungsoperator nach (w)char* oder int o.ä. ?

    Ich vermute, dass Du gar kein malloc/new brauchst, wenn Du nur lesen auf den Path zugreifen willst. Wenn das die o.g. Zuweiseung und der Aufruf von SucheTeilString() problemlos klappen, wird wohl auch ein direkter Aufruf

    SucheTeilString(csPath);
    

    funktionieren. Ggf. gibt es in der Klasse von csPath auch eine explizite Methode, um einen portablen Typen herauszugeben (so wie string::c_str()) ....

    Wenn Du tatsächlich eine Kopie brauchst, würde ich Dir auf jeden Fall dazu raten, (w)string (statt (w)char) zu verwenden oder mit new/delete zu arbeiten. Das finde ich deutlich weniger verwirrend (weil Du direkt Typen angeben kannst und nicht über sizeof() Speichergrößen berücksichtigen musst).

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Dass das nichtmal zu einer Warnung führt, kann ich mir kaum vorstellen. Was hat denn "csPath" für einen Typ (String ?) ? Hat der einen Konvertierungsoperator nach (w)char* oder int o.ä. ?

    Wie er geschrieben hat, ist das ein CString (MFC-Klasse), und der HAT einen operator TCHAR*.



  • CStoll schrieb:

    ...Wie er geschrieben hat, ist das ein CString (MFC-Klasse)...

    Aha ! Vielen Dank !
    Da ich keine MFC-Erfahrung habe, war mir das nicht klar und ich habe den Kommentar "Inhalt einer CString Variable" als fachliche Aussage aufgefasst.

    Tja, wieder was dazugelernt.

    Gruß,

    Simon2.

    P.S.: Vielleicht wieder ein gutes Beispiel dafür, dass Konversionsoperatoren oftmals mehr Verwirrung stiften als sie beseitigen (weswegen sie auch "Konfusionsoperatoren" genannt werden) ... 😉



  • @CStoll besten dank, so funktioniert es! 👍

    @Simon2, ich weis nicht warum der mir keine warnung oder fehler ausgegeben hat beim debuggen! Es ist auch richtig das ich nur in dem CString lesen möchte, nichts ändern, es wurde einfach so verlangt, und ich wollte es eigentlich auch für mich wissen wie das verwendet wird!

    also, danke noch mal!
    🙂



  • Na, wenn du den Text nur lesen willst, kannst du dir das ganze Kopieren ersparen und deinen CString direkt an die Suchfunktion weitergeben. (noch besser ist natürlich, du nutzt entsprechende Methoden des CStrings dafür)

    @Simon: Ja, da dürftest du recht haben. Aber M$ war offenbar der Meinung, daß an der Stelle ein Konversionsoperator nötig ist (std::string hat bekanntlich keinen - und überhaupt sind solche Operatoren recht sparsam in der Standard-Bibliothek vertreten).



  • pixel schrieb:

    @CStoll besten dank, so funktioniert es! 👍

    @Simon2, ich weis nicht warum der mir keine warnung oder fehler ausgegeben hat beim debuggen! ...

    Hi,

    beim compile hätte ich einen Fehler/eine Warnung erwartet, aber die Antwort hat CStoll schon gegeben mit

    CStoll schrieb:

    ...CString (MFC-Klasse), und der HAT einen operator TCHAR*.

    Da sieht der Comnpiler bei "acPath = csPath;":
    - linke Seite: wchar_t*
    - rechte Seite: CString (wohlgemerkt: KEIN Pointer !)
    und fragt sich: "Wie soll ich das zusammenbringen ?"
    Dann findet er den "Konversionsoperator con CString", der sagt, wie man aus einem CString einen TCHAR* macht und da gibt es bestimmt (kenne jetzt auch die Deklaration von TCHAR* nicht) einen einfachen Weg nach wchar_t* ....
    Er macht also den Umweg
    CString -> TCHAR* -> w_char_t
    ... und da der Compiler das "heimlich unter der Haube" macht, fällt es keinem auf.

    Aber schön, dass Dir geholfen wurde.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Dann findet er den "Konversionsoperator con CString", der sagt, wie man aus einem CString einen TCHAR* macht und da gibt es bestimmt (kenne jetzt auch die Deklaration von TCHAR* nicht) einen einfachen Weg nach wchar_t* ....

    TCHAR ist ein Synonym für char bzw. wchar_t, je nachdem, ob du für UNICODE programmierst oder nicht (siehe dazu auch guenni's Artikel im Magazin).


Anmelden zum Antworten