[c] Pointerstuff
-
Hallo!
Ich habe ein kleines Pointerproblem(chen). Ich habe in meinem Programm ein struct, für das ich eine "create"-funktion haben möchte, da das struct ziemlich oft mit ganz speziellen Werten gefüllt werden muss.
Nun bekomme ich vom Compiler die Warnung: "function returns address of local variable". Heisst das, das wenn die "create" - funktion beendet ist, der Pointer dann auch ungültig wird ?
Ich habe das Problem mal ganz einfach nachgebildet und zwei Varianten geschrieben. Was ist der Unterschied zwischen den beiden, welche ist besser oder kann man das grundsätzlich anders machen ?
Hier ein einfaches Struct:
typedef struct{ int a; int b; }my_struct;
build-fkt , Variante 1 (mit Compiler-Warnung)
my_struct* build_struct1(void){ my_struct test; test.a = 2; test.b = 393; return &test; }
build-fkt , Variante 2
my_struct* build_struct2(void){ my_struct* test = (my_struct*)malloc(sizeof(my_struct)); test->a = 2; test->b = 222; return test; }
Zur Zeit geh ich auf nummer sicher und mache das so:
my_struct build_struct(void){ my_struct test; test.a = 2; test.b = 222; return test; }
Das unbequeme ist nur, das ich an aufrufender Stelle einen Pointer auf das struct brauche.
-
my_struct* build_struct1(void){ my_struct test; test.a = 2; test.b = 393; return &test; }
schlechte idee... test gibt es nach durchlauf von build_struct1 nicht mehr du hast also nur ne adresse von was, was es irgendwann mal gab...
my_struct* build_struct2(void){ my_struct* test = (my_struct*)malloc(sizeof(my_struct)); test->a = 2; test->b = 222; return test; }
geht... aber unschön da der aufrufer den speicher auch wieder freigeben muss...
my_struct build_struct(void){ my_struct test; test.a = 2; test.b = 222; return test; }
das funktioniert weil test kopiert wird bzw. du es gleich nem anderen struct zuweist...
-
Also belasse ich es bei meiner Version.
Jetzt hab ich noch ne Frage:
Dieses Fragment wird anstandslos ausgeführt (Ausgabe: 123):
char a[3] = "123"; char b[3]; strcpy(&b,&a); printf("%s",b);
Nur warnt mich der compiler : "passing arg 1 of `strcpy' from incompatible pointer type" .
Was läuft falsch ? Und was ist der Unterschied zwischen "strcpy" und "memcpy" ?
-
Erstmal sollte der Aufruf von strcpy so aussehen
strcpy(b, a); // bzw strcpy(&b[0], &a[0]);
Zweitens hat das Programm so trotzdem undefiniertes Verhalten.
Seltsam, dass dein Compiler sowaschar a[3] = "123";
frisst. Denn "123" sind eigentlich 4 Zeichen, da du noch das abschliessenden Nullzeichen bei C-Strings beachten musst, entsprechend auch bei deinem Zielpuffer. Du kannst ja mal folgendes ausprobieren
const char a[] = "123"; size_t len = sizeof(a) / sizeof(char);
Damit kannst du die Anzahl der Elemente von a bestimmen (ürigens solltest du Stringliterale immer const definieren, da das ändern solcher undefiniertes Verhalten ergibt).
Der Unterschied zwischen strcpy und memcpy ist einfach der, dass strcpy nullterminierte Strings (C-Strings) kopiert, memcpy einfach nur rohe Daten. Deshalb musst du zB bei memcpy auch die Länge angeben, bei strcpy kann die Funktion die Länge durch das abschliessende Nullzeichen selbst bestimmen.