Anzeige:
Ergebnis 1 bis 7 von 7

Thema: [C] wann malloc (bei glib)

  1. #1
    Registrierter Benutzer
    Registriert seit
    11.09.2003
    Beiträge
    100

    [C] wann malloc (bei glib)

    Hallo, bin etwas verwirrt, was die Benutzung von malloc angeht.
    Das hier war mein Kenntnisstand:

    Bei einfachen Typen (int, char, ...) braucht man's nicht (die Variable landet dann im Stack). Aber wie ist's bei structs? Ich weiß, die kann man entweder direkt ansprechen (x.y) oder über einen pointer (x->y), aber muss ich für alles, worauf ich per pointer zugreifen will, erst per malloc() Speicher reservieren? Ich glaube nicht, denn bei meinem konkreten Problem sieht die Sache so aus:
    Code:
    GList *list = NULL;
    int i = 1;
    g_list_prepend(list, i);
    
    GList *l;
    for(l = list;
        l;
        l = l->next) {
        printf("Element %d\n", l->data);
    }
    Das funktioniert, da wird mit genau das eine Element angezeigt und es gibt keinen Fehler. Hier hab' ich für GList keinen Speicher reserviert, sondern den list-pointer auf NULL zeigen lassen. Das ist wohl auch der richtige Weg, GList zu benutzen.
    Per malloc (genauer gesagt g_malloc, was in g_new benutzt wird) funktioniert's nicht:
    Code:
    GList *list = g_new(GList, 10); // potenziell 10 Element?!
    int i = 1;
    g_list_prepend(list, i);
    
    GList *l;
    for(l = list;
        l;
        l = l->next) {
        printf("Element %d\n", l->data);
    }
    Und hier zeigt er mir noch Element 1 an, will dann aber auf Element 2 gehen, weil der temporäre GList-Pointer l offensichtlich nicht NULL ist, dann gibt's nen segmentation fault. Ich versteh jetzt nicht warum. Werden bei g_new(GList, 10) gleich 10 GList-Instanzen aufgebaut mit 10 next- und prev-Pointern, die sich gegenseitig referenzieren? Und wieso ist deren data-Pointer dann nicht =NULL? Der Code funktioniert übrigens auch nicht, wenn ich g_new(GList, 1) sage, da will er auch auf ein zweites Element gehen und stürzt mit nem segfault ab.

    Aber das nur um meine konkreten Probleme zu schildern. Generell würde ich gerne wissen: wann nutze ich malloc und wann nicht?

    - Ist das abhängig davon, ob ich per Pointer drauf zugreife?
    - Ist das abhängig vom Datentyp?
    - Ist das abhängig von der Anzahl der Elemente (i.e. ich sollte malloc nur nutzen, wenn ich 100kB und mehr Speicher für meine Daten benötige)?
    - Ist das abhängig davon, ob ich den stack oder den heap nutzen will (und den stack will ich ja nicht zumüllen, also geht das bestimmt auch in die Richtung, dass ich ab 100kB immer den heap nutzen sollte und daher ab 100kB immer malloc verwenden sollte)?

  2. #2
    Registrierter Benutzer
    Registriert seit
    14.01.2002
    Beiträge
    657
    hi,

    grundsätzlich ist es so:
    Variablen die du nutzt werden auf dem Stack angelegt.
    Wenn du Daten im Heap speichern willst, musst du dort speicher mit malloc reservieren.


    int i; // variable i ist im stack
    struct x datum; // datum ist im stack; ansprechen mit datum.member

    int *ip; // pointer auf ein int, ip selbst ist auf dem stack, ist allerdings nur eine adresse auf einen speicherbereich (nicht initialisiert). ip braucht 32 bzw 64bit auf dem stack

    struct x* datump // pointer auf ein struct x, datump ist auf dem stack und ist 32 bzw 64bit groß


    in den unteren zwei fällen hast du noch keinen speicherplatz für deinen integer bzw struct x. diesen _kannst_ du auf dem heap anlegen oder aber einen stack bereich nutzen:

    Stack bereich:
    ip = &i;
    nun kannst du mit *ip = 4 den wert auf den ip zeigt ändern (und damit änderst du auch gleich i mit)

    datump = &datum;
    datump->member = xxx;
    (*datump).member = xxx;

    die beiden zugriffsvarianten machen dasgleiche der * sorgt dafür das dereferenziert wird (Wenn dir das nicht sagt:google)

    hoffe der unterschied wurde klar.

  3. #3
    Registrierter Benutzer
    Registriert seit
    11.09.2003
    Beiträge
    100
    Schon mal vielen Dank. Ich kann also machen, was ich will.
    Aber wie sollte ich es denn machen? Große Datenmengen in den heap und kleine in den stack, oder?

  4. #4
    Registrierter Benutzer
    Registriert seit
    14.01.2002
    Beiträge
    657
    beim verlassen einer funktion wird der stack autom. freigegeben.
    dh wenn du daten länger brauchst musst du den heap benutzen.

    es ist aber schneller und effizienter daten auf dem stack anzulegen

  5. #5
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Zitat Zitat von ThorstenHirsch Beitrag anzeigen
    Ich glaube nicht, denn bei meinem konkreten Problem sieht die Sache so aus:
    Das ist schon korrekt, allerdings ist in deinem Beispiel ein Funktionsaufruf beteilgt (g_list_prepend) und das Anfordern des Speicher könnte dort passieren.
    Natürlich hast du ja schon durch Experimentieren raus gefunden, dass das der Fall ist, aber nur um etwaige Zweifel aus zu räumen:

    "Allocates space for one GList element. It is called by g_list_append(), g_list_prepend(), g_list_insert() and g_list_insert_sorted() and so is rarely used on its own."

    Aus der Dokumentation zu g_list_alloc(), also der Function, mit der man eine leere GList erzeugen könnte (was man in den meisten Fällen nicht tut weil man das implizit beim Befüllen erledigt bekommt).

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  6. #6
    Registrierter Benutzer
    Registriert seit
    11.09.2003
    Beiträge
    100
    Aaah, merci! So viel Gnome-Kompetenz von nem User mit KDE-Avatar...

  7. #7
    Registrierter Benutzer Avatar von sommerfee
    Registriert seit
    02.07.2006
    Beiträge
    1.604
    Ergänzung:

    Falsch ist:
    Code:
    g_list_prepend(list, i);
    Richtig ist:
    Code:
    list = g_list_prepend(list, i);
    Siehe: http://developer.gnome.org/glib/stab...g-list-prepend

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •