Problem mit malloc



  • SeppJ schrieb:

    Aufgabe 1:

    int a = 1;
    foo(a);
    printf("%d", a);
    

    Schreibe eine Funktion foo, so dass dieses Programm "0" ausgibt.

    Aufgabe 2:

    int i;
    int *a = &i;
    bar(a);
    printf("%p", a);
    

    Schreibe eine Funktion bar, so dass dieses Programm "0x0" ausgibt. Tipp: Vielleicht hilft es, die Lösung von Aufgabe 1 zu verstehen und nicht aus dem Internet/Lehrbuch zu kopieren. Beim Programmieren musst du von jedem Zeichen in deinem Programm wissen, was es bedeutet und warum du es setzt.

    ich blicks einfach nicht mit diesen pointern...

    Aufgabe 1:
    das wär jetzt meine idee:

    void foo(int *a)
    {
        &a=0;
    }
    

    Aufgabe 2:

    void bar(int *a)
    {
         *a=0;
    }
    

    lösung?


  • Mod

    Die compilieren nicht einmal. Nicht raten. Programmieren. Dazu gehört auch, seine Programme mal auszuprobieren. Oder auch mal den Stolz zu überwinden und ins dritte Kapitel des Lehrbuchs zurück zu springen.



  • Pointer sind auch nur Variablen.
    Sie haben halt Adressen als Werte.

    Und man kann auch die Adresse bestimmen, wo ein Pointer seinen Wert abspeichert.



  • +++--- schrieb:

    void foo(int *a)
    {
        &a=0;
    }
    

    '&' steht in diesem Fall für den Adress-Operator, du musst verstehen, dass du eine Adresse prinzipiell nicht ändern kannst, du kannst nur die Daten, die an dieser Adressen stehen, lesen und schreiben, und dafür sind Zeiger da und hierbei insbesondere die Dereferenzierung eines Zeigers mittels '*'.



  • SeppJ schrieb:

    Bevor du dich aber zu sehr auf diese Lösung versteifst (Referenzübergabe solltest du trotzdem lernen): Designtodsünde! Nicht fortfahren, sofort umkehren. Man übergibt keine Verantwortung aus einer Funktion heraus oder hinein! Für das Freigeben von Ressourcen ist immer die Programmlogikebene verantwortlich, die diese auch angefordert hat. Wenn du dich nicht daran hältst, endet das so sicher in Spaghetticode wir goto und globale Variablen.

    was genau meinst du jetzt mit designtodsünde? call by reference?



  • SeppK schrieb:

    was genau meinst du jetzt mit designtodsünde? call by reference?

    Nein. Verantwortungsabgabe. Wenn ich malloc mache, dann muss ich auch free machen.

    Wenn man nun in einer Funktion Speicher reserviert und diesen aus der Funktion herausgibt, dann übergibt man die Verantwortung für das free ja dem Aufrufer - das sollte idR gemieden werden.

    Ich weiß nicht ob ich Todsünde unterschreiben würde, aber man sollte es sich schon sehr sehr sehr sehr gut überlegen, ob man das wirklich so machen will.

    Der richtige Weg ist, dass der Aufrufer den Speicher zur Verfügung stellt.



  • Shade Of Mine schrieb:

    SeppK schrieb:

    was genau meinst du jetzt mit designtodsünde? call by reference?

    Nein. Verantwortungsabgabe. Wenn ich malloc mache, dann muss ich auch free machen.

    Wenn man nun in einer Funktion Speicher reserviert und diesen aus der Funktion herausgibt, dann übergibt man die Verantwortung für das free ja dem Aufrufer - das sollte idR gemieden werden.

    Ich weiß nicht ob ich Todsünde unterschreiben würde, aber man sollte es sich schon sehr sehr sehr sehr gut überlegen, ob man das wirklich so machen will.

    Der richtige Weg ist, dass der Aufrufer den Speicher zur Verfügung stellt.

    ok, aber es gibt diverse libs und engines, die dass anscheinend machen?!?


  • Mod

    Shade of Dein schrieb:

    ok, aber es gibt diverse libs und engines, die dass anscheinend machen?!?

    Meistens machen die aber etwas nach dem Muster

    EngineHandleType handle;
    EngineAllocator(handle);
    // ...
    EngineFree(handle);
    

    Da mögen dann natürlich mallocs und frees dahinter stehen, aber die Verantwortung für das Handle bleibt auf einer Ebene. Das ist dann vollkommen ok. Besser geht es in C nicht.

    Der Fall wo man wirklich free auf etwas aus einer Bibliothek aufrufen muss ist mir erst einmal vorgekommen (der GCC hat da eine grauenhafte Erweiterung, die ich nicht auch noch bewerben möchte) und sollte mMn als ein starkes Zeichen für eine schlechte Bibliothek gelten.



  • gut, aber sowas wie

    struct test{
          int a;
          int b;
    };
    
    void fill_struct(char *memory,struct test a abc)
    {
         memcpy(&abc.a,&memory[0],4);
         memcpy(&abc.b,&memory[4],4);
    }
    

    das ist aber ok und erlaubt?



  • edit: es sollte natürlich "struct test abc" heißen.


  • Mod

    öäü schrieb:

    das ist aber ok und erlaubt?

    Erlaubt natürlich sowieso, aber auch ok. Man gibt Daten an, die Funktion macht etwas damit.

    Der konkrete Code ist hier natürlich schrecklich: Nicht const-korrekt, unnötig unportabel und zudem soll das wohl ein Zeiger auf das struct sein, sonst füllst du dir eine lokale Kopie.



  • SeppJ schrieb:

    öäü schrieb:

    das ist aber ok und erlaubt?

    Erlaubt natürlich sowieso, aber auch ok. Man gibt Daten an, die Funktion macht etwas damit.

    Der konkrete Code ist hier natürlich schrecklich: Nicht const-korrekt, unnötig unportabel und zudem soll das wohl ein Zeiger auf das struct sein, sonst füllst du dir eine lokale Kopie.

    WAS?

    was meinst du denn mit "nicht const-korrekt"? wie hättest du das denn gemacht? ok, pointer, aber sonst?


Anmelden zum Antworten