Probleme mit Speicherallokation, malloc aber free nicht möglich



  • Hallo,

    wieso kann ich einen Zeiger *p so initialisieren:

    char *p = (char *) malloc(21);  // 20 Bytes allokieren
    

    Mit strcpy() Text hineinkopieren:

    strcpy(p, "Hugo 4711");
    

    und bekomme dann bei späterem free() einen Segmentation Fault?

    Mir ist dieses Problem auch schon passiert, als ich versuchte, ein dynamisches Array of Structs zu bauen, dessen Speicherbereich ich beim Beenden des Programms dann freizugeben versuchte.

    Fest steht, dass die Pointer immer existieren und einen gültigen Speicherbereich adressieren. Jedesmal jedoch bei free() gibts bei der Ausführung Probleme...

    Gruß
    Prog



  • Das muss am Compiler liegen, oder an Sonnenflecken oder Erdstrahlen. Normalerweise ist das Verhalten dieses Programms wohldefiniert (es sei denn malloc liefert 0 zurück, was aber auf deiner Maschine eine Wahrscheinlichkeit von ziemlich genau 0 hat):

    #include <stdlib.h>
    #include <string.h>
    int main() {
      char *p = malloc(21);
      strcpy(p, "Hugo 4711");
      free(p);
    }
    

    BTW ist der Kommentar "20 Bytes allokieren" an Überflüssigkeit nicht zu überbieten, insbesondere wenn du 21 Bytes allozierst.



  • BTW ist der Kommentar "20 Bytes allokieren" an Überflüssigkeit nicht zu überbieten, insbesondere wenn du 21 Bytes allozierst.

    Das stimmt natürlich. Ich meinte natürlich 20 Zeichen, da ja das 21te '\0' ist.

    Ich habe nun dieses Problem noch soz. Funktionsübergreifend. Ich habe einen Zeiger auf ein globales Struct:

    CUBE *cubeInfo;
    

    Initialisiere dieses:

    int Init() {
      cubeInfo = (CUBE) calloc(1, sizeof(CUBE));
      if(!cubeInfo)
         return -1;
      // Initialisieren
      cubeInfo.xyz = 0;
    }
    

    Will dann später darauf zugreifen:

    GLvoid DrawGLScene() {
      float x = cubeInfo.xyz + 1.0f; // hier der Seg-Fault
      //...
    }
    

    1. bekomme ich beim Zugriff auf die korrekt initialisierte cubeInfo einen Segmentation Fault

    2. kann ich den Speicher ebenfalls nicht mit free() freigeben:

    void KillScene() {
      if(cubeInfo)
        free(cubeInfo);
    }
    

    Die Funktionen werden wie folgt durch eine WinProc() in den Message-Handlern aufgerufen (Sorry für das WIN32-Topic)

    WM_CREATE:
    Init();
    WM_PAINT:
    DrawGLScene();
    WM_DESTROY:
    KillScene();

    Für Ideen wäre ich dankbar!
    Prog



  • Sieht nach einem Compilerproblem aus. Welchen Compiler in welcher Version nutzt du.

    Habe diene Code Stücke in MSVC 6.0 Porfessional compiliert und keinerlei Probleme, weder in der Debug noch in der Release version. Der Speicher sieht auch vernünftig aus.



  • Ich meinte natürlich 20 Zeichen, da ja das 21te '\0' ist.

    ???

    cubeInfo = (CUBE) calloc(1, sizeof(CUBE)); 
      if(!cubeInfo) 
         return -1; 
      cubeInfo.xyz = 0;
    

    cubeInfo ist doch ein Pointer, was soll dann cubeInfo.xyz sein? Würdest du dir bitte die Mühe machen und korrekten Code posten? Was ist CUBE für ein Typ? Wieso kann man einen void-Pointer nach CUBE casten? Oder ist das wieder ein Tippfehler?

    Bitte reduzier dein Problem soweit, dass du es hier posten kannst, es aber immer noch compilierbar ist und den Fehler verursacht.



  • und nicht nur auf den Cast kannst du verzichten, sondern auch auf das prüfen auf NULL Zeiger beim freigeben, darum kümmert sich free schon ganz allein!



  • Tut mir leid, ich hatte mein Struct bereits in ein statisches geändert, deshalb die Punkt-Notation. Weshalb der Code dann bei PAD funktionierte ist mir ein Rätsel 😉 Außerdem hatte ich den Code nicht kopiert, sondern direkt eingetippt, was wohl ein Fehler war - sorry.

    Zu Euren Antworten:

    Ich meinte natürlich 20 Zeichen, da ja das 21te '\0' ist.

    Damit bezog ich mich auf mein erstes Beispiel, in dem ich char* initialisiert hatte, die dann ja ein Array mit 21 Zeichen darstellen. Das 21te Zeichen im Array ist die Endekennung eines Strings, da ich dieses Array ja als C-String verwende...

    Wieso kann ich auf einen Cast verzichten? Dann erzeugt der Compiler einen Fehler, den ich lediglich durch explizite Typumwandlung verhindern kann. Das Problem war, dass ich auf CUBE gecastet habe (in meinem fehlerhaft getippten Codeschnipsel), wobei ich natürlich in meinem Code auf CUBE* caste!

    Die Lösung habe ich allerdings gerade gefunden:

    Ich hatte in MEINEM Code in der Init() Funktion die globale Variable cubeInfo zur Lokalen gemacht, indem ich schrieb:

    CUBE cubeInfo = (CUBE *) calloc(1, sizeof(CUBE));
    

    Wie man erkennen kann hatte ich beim "abtippen" den Fehler nicht mit übernommen.

    Entschuldigt, dass ich Euch die Bandbreite stahl... 😉

    Gruß
    Prog



  • Wieso kann ich auf einen Cast verzichten? Dann erzeugt der Compiler einen Fehler, den ich lediglich durch explizite Typumwandlung verhindern kann

    weil du einen C++ Compiler und keinen C Compiler benutzt 🙄

    hättest du einen C Compiler genommen, hättest du dir den Cast gespart und den Fehler gesehen 🙂

    Damit bezog ich mich auf mein erstes Beispiel, in dem ich char* initialisiert hatte, die dann ja ein Array mit 21 Zeichen darstellen. Das 21te Zeichen im Array ist die Endekennung eines Strings, da ich dieses Array ja als C-String verwende...

    du reservierst Platz für 21 Zeichen, '\0' ist wie du selbst sagst auch ein Zeichen. Aber solche Kommentare sind sinnlos, wer malloc(21); nicht versteht, sollte dein Programm eh nicht lesen 🙂



  • ProgRulez schrieb:

    Wieso kann ich auf einen Cast verzichten? Dann erzeugt der Compiler einen Fehler, den ich lediglich durch explizite Typumwandlung verhindern kann.

    Dann programmierst du in C++, und bist hier im falschen Forum.



  • Das ist kein Rätsel, ich hatte den Code abgettippt und nicht kopiert.

    Was ich bekam war

    d:\tmp\te1\te1.cpp(156) : error C2228: Der linke Teil von '.xyz' muss eine Klasse/Struktur/Union sein

    Das hatte ich schnell korrigiert und dann liefs. Das ich beim Cast oben das
    '*' dazugeschrieben hatte, habe ich nicht bemerkt

    Man sollte halt kopieren und nicht abtippen


Anmelden zum Antworten