String ausgeben: Speicherverletzung?
-
Hi, ich habe ein Problem mit einem String-Array.
Also ich möchte Strings in einem Array speichern:
char *names[100];
Und dann setze ich einen Wert in einer Funktion:
names[2] = name;
Und will mir den Wert in einer anderen funktion holen:
printf("%s - %s", names[2], name);Aber was heraus kommt ist das:
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠■- is
Wenn ich aber versuche den Wert von names[2] in der gleichen Funktion, in der ich den Wert gesetzt habe, auszugeben, dann funktioniert alles.
*PS: kurze Frage:
bei int Funktionen kann man doch den Wert einer Variablen zurückgeben, oder?:int a{ int i = 2; return i; }
geht das auch bei string Funktionen? z.B.:
char *a{ oder char a[]{ char *b = "h"; return b; }
-
frank2 schrieb:
Hi, ich habe ein Problem mit einem String-Array.
Also ich möchte Strings in einem Array speichern:
char *names[100];
Und dann setze ich einen Wert in einer Funktion:
names[2] = name;
Und will mir den Wert in einer anderen funktion holen:
printf("%s - %s", names[2], name);Aber was heraus kommt ist das:
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠■- is
Wenn ich aber versuche den Wert von names[2] in der gleichen Funktion, in der ich den Wert gesetzt habe, auszugeben, dann funktioniert alles.
Das geht deshalb schief, weil Du nur Speicher für das Array von Pointern (statisch) reservierst. Du musst es entweder vollständig dynamisch machen (malloc/free/...) oder so:
char names[100][100];
frank2 schrieb:
*PS: kurze Frage:
bei int Funktionen kann man doch den Wert einer Variablen zurückgeben, oder?:int a{ int i = 2; return i; }
Ja, aber Deine Funktionssyntax ist falsch:
int func() { int i = 2; return i; }
frank2 schrieb:
geht das auch bei string Funktionen? z.B.:
char *a{ oder char a[]{ char *b = "h"; return b; }
Nein. Denn bei der "Int-Funktion" wird der Wert via Kopie zurückgeben. Hier gibst Du die Adresse eines C-Strings zurück, welcher gar nicht mehr existiert, wenn die Funktion verlassen wird, da 'b' nur lokal existiert. Ein funktionierendes Beispiel wäre (ist aber trotzdem unschön):
const char* func1() { static char szBuffer[100]; // Etwas mit szBuffer machen... return (szBuffer); }
static sorgt hier dafür, dass "szBuffer" auch nach dem Verlassen der Funktion existiert und der zurückgegebene Zeiger weiterhin gültig ist
.
-
Wird bei dem folgenden Code denn keine Kopie gemacht?
char a[]() { char b[50] = "hallo"; return b; }
Wie würde denn in diesem Fall malloc (free?) funktionieren?
Ach.. und noch danke für deine bisherige Hilfe
-
frank2 schrieb:
Wird bei dem folgenden Code denn keine Kopie gemacht?
char a[]() { char b[50] = "hallo"; return b; }
Doch, aber nur von der Adresse. Beim Verlassen der "Funktion" (Du solltest Dir nochmal anschauen, wie Funktionen syntaktisch aufgebaut werden, das was Du dort geschrieben ist irgendein murks :p ) wird die Variable 'b' wieder "gelöscht" (also vom Stack der Funktion gepoppt) und der Zeiger der -kopiert- zurückgegeben wird, ist ungültig.
frank2 schrieb:
Wie würde denn in diesem Fall malloc (free?) funktionieren?
zum Beispiel so, aber gut ist das trotzdem nicht, da wenn man nach dem Aufruf das free(...) vergisst, bleibt nicht-freigegebener Speicher im RAM liegen:
// Funktionsdefinition: char* func() { char* p = (char*)malloc(100); // irgendwas mit p machen... return (p); } // Verwendung/Aufruf der Funktion: char* buffer = func(); // hier könnte man nochwas mit buffer machen; übrigens buffer entspricht hier p in der Funktion; das sollte aber klar sein free(buffer); // Speicher von buffer bzw. p (von der Funktion allokiert) freigeben
frank2 schrieb:
Ach.. und noch danke für deine bisherige Hilfe
Jop, kein Problem
.
-
CodeFinder schrieb:
frank2 schrieb:
geht das auch bei string Funktionen? z.B.:
char *a() { char *b = "h"; return b; }
Nein. Denn bei der "Int-Funktion" wird der Wert via Kopie zurückgeben. Hier gibst Du die Adresse eines C-Strings zurück, welcher gar nicht mehr existiert, wenn die Funktion verlassen wird, da 'b' nur lokal existiert.
Aber sicher geht das!
Es wird ja nicht die Adresse von b zurückgegeben, sondern
die Adresse des Strings auf den b verweist (also auf den konstanten
String "h" in diesem Fall)
-
Jupp, hast Recht, hab das verwechselt mit:
char *a() { char b[] = "h"; return b; }