Problem mit malloc
-
Steht doch da: memory wird unitialisiert benutzt. Merke: Der Compiler hat immer Recht. Du hingegen solltest dir nochmal Parameterübergabe an Funktionen ansehen, insbesondere call by reference, bzw. die Übergabe per Pointer die man in C benutzen muss, um diesen Effekt zu erreichen. Tipp: Wenn du
void foo(int* a);
benutzen musst, um einen int zu verändern, was ist wohl nötig um einen Zeigertypen zu verändern?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.
Im übrigen ist es schön zu sehen, dass du anscheinend nicht den Tipp mit dem Cast angeguckt hast und stattdessen immer noch deinem Schrottlehrbuch/-tutorial folgst.
-
SeppJ schrieb:
Steht doch da: memory wird unitialisiert benutzt. Merke: Der Compiler hat immer Recht. Du hingegen solltest dir nochmal Parameterübergabe an Funktionen ansehen, insbesondere call by reference, bzw. die Übergabe per Pointer die man in C benutzen muss, um diesen Effekt zu erreichen. Tipp: Wenn du
void foo(int* a);
benutzen musst, um einen int zu verändern, was ist wohl nötig um einen Zeigertypen zu verändern?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.
Im übrigen ist es schön zu sehen, dass du anscheinend nicht den Tipp mit dem Cast angeguckt hast und stattdessen immer noch deinem Schrottlehrbuch/-tutorial folgst.
also irgendwie versteh ich deinen beitrag nicht, obwohl ich schon länger c lerne
du meinst also ich soll, wenn ich etwas mit einem char-pointer in einer funktion machen will, eine char pointer zurückgeben, und kein int? aber wie soll ich denn dann andere rückgabe-werte zurückgeben (z.b. wenn ein fehler auftritt.)
meinst du das jetzt so:
char *test_funktion(char *memory,int s) { memory=(char *)malloc(s); if(memory==NULL) { return 1; } return memory; }
... oder wie?
-
p.s.: anscheinend hab ich hier was überlesen... was meinst du mit dem "cast"? mach ich das nicht bei malloc ("**(char *)**malloc....")?
-
Einen Cast dieser deiner "Güte" setzen nur Leute ein, die nicht wissen, was sie machen oder/und wollen (C oder C++).
Zu einem malloc gehört auch immer ein free, und das free muss für ein sinnvolles Design immer auf derselben Funktions(Aufruf)-Ebene liegen, wie das malloc, also in etwaint main() { char *p=malloc(100); if( funktion(p)==irgendeinfehlercode ) { ... } free(p); ... }
-
*** edit *** schrieb:
p.s.: anscheinend hab ich hier was überlesen... was meinst du mit dem "cast"? mach ich das nicht bei malloc ("**(char *)**malloc....")?
Warum tust du das?
du meinst also ich soll, wenn ich etwas mit einem char-pointer in einer funktion machen will, eine char pointer zurückgeben, und kein int?
Nein. Das war ein Beispiel, damit ich dir nicht die Lösung vorkaue und du nichts kapierst. Versuch mal drüber nachzudenken, was ich gesagt habe.
meinst du das jetzt so:
WTF?
Nein, so meinte ich das ganz sicher nicht.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.
-
ok das hab ich jetzt verstanden.
also darf wohl eine "externe" funktion (ich mein damit funktionen außerhalb der hauptfunktion) keinen speicherplatz allozieren, bzw. freigeben?
-
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?
-
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?!?
-
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.
-
öäü 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?