Forum: Compiler & IDEs String innerhalb und ausserhaln von Funktionen


von Peter (Gast)


Lesenswert?

Hallo,
ich habe eine ganz dumme und simple Frage. Ich habe einen pointer auf 
ein char array in c in einer funktion und alles ist fein. die Pointer 
hole ich mir als teil einer referenzierten Struktur in mein Hauptprogram 
und dort zeigt der pointer ins nichts.
Wie kann ich das lösen und was muss ich am Ende frei geben?

typedef struct{
  int av;
  int an;
  char *p_vor;
  char *p_nach;
  char vor[4];
  char nach[7];
}V_N_Name;

void expandString3(V_N_Name *innen){
  char vorn[] = {"Gabi"};
  char nachn[] = {"Blaubeere"};
  innen->an = 7;
  innen->av = 4;
  innen->p_vor = &vorn[0];
  printf("expand String3: Vorname ist %s\n", innen->p_vor);
  innen->p_nach = &nachn[0];
  printf("expand String3: Nachname ist %s\n", innen->p_nach);
}
  expandString3(&aussen);
  printf("Der vollständige Name meiner lieben Frau ist: %s 
s\n",aussen.p_vor, aussen.p_nach);


Ergebnis:
expand String3: Vorname ist Gabi
expand String3: Nachname ist Blaubeere
Der vollständige Name meiner lieben Frau ist:  !@

Mein 2ter Ansatz war:

void expandString2(V_N_Name *innen){
  innen->an = 7;
  innen->av = 4;
  printf("expandString2: Vorname: %s\n", innen->vor);
  strcat(innen->vor,"Gabi");
  printf("expandString2: Vorname: %s\n", innen->vor);
  strcat(innen->nach,"Blaubeere");
  printf("expandString2: Vorname: %s\n", innen->vor);
  printf("expandString2: Nachname: %s\n", innen->nach);
  }

  expandString2(&aussen);
  printf("Der vollständige Name meiner frau ist: %s %s\n",aussen.vor, 
aussen.nach);
  printf("Vorname: %s\n", aussen.vor);
  printf("Nachname: %s\n", aussen.nach);

Ergebnis:
expandString2: Vorname:
expandString2: Vorname: Gabi
expandString2: Vorname: GabiBlaubeere
expandString2: Nachname: Blaubeere
Der vollständige Name meiner frau ist: GabiBlaubeere Blaubeere


Was mache ich in den Beispielen falsch? Vielen Dank für Eure Hilfe.
/Pepe

von moep (Gast)


Lesenswert?

Hallo Peter,

die Strings vorn und nachn leben auf dem Stack. D.h.
sie sind lokal in deiner Funktion expandString3 und werden
gelöscht, wenn die Funktion zurückkehrt.

von Klaus W. (mfgkw)


Lesenswert?

Der erste Fehler ist, daß deine Programme unvollständig sind (wo ist 
aussen definiert?).

Der zweite ist, daß sie unformatiert sind und schlecht zu entziffern.

Der dritte, daß im zweiten Fall für Vor- und Nachname nirgends Speicher 
beschafft wird (worauf zeigt innen-Yvor ?). => C-Grundlagen!

von Klaus W. (mfgkw)


Lesenswert?

moep schrieb:
> Hallo Peter,
>
> die Strings vorn und nachn leben auf dem Stack. D.h.
> sie sind lokal in deiner Funktion expandString3 und werden
> gelöscht, wenn die Funktion zurückkehrt.

ja, auch das noch.

von Helfer (Gast)


Lesenswert?

void expandString3(V_N_Name *innen){
  char vorn[] = {"Gabi"};        <============ nur zur Laufzeit von
  char nachn[] = {"Blaubeere"};  <============ expandString3 gültig!
  innen->an = 7;
  innen->av = 4;
  innen->p_vor = &vorn[0];

Besser

void expandString3(V_N_Name *innen){
  static char vorn[] = {"Gabi"};
  static char nachn[] = {"Blaubeere"};
  innen->an = 7;
  innen->av = 4;
  innen->p_vor = &vorn[0];

von Peter (Gast)


Lesenswert?

Sorry, als erstes ich habe nur teile raus kopiert.
In der Main ist aussen schon deklariert.

  V_N_Name aussen;

Die Software baut ja auch.

"Hallo Peter,

die Strings vorn und nachn leben auf dem Stack. D.h.
sie sind lokal in deiner Funktion expandString3 und werden
gelöscht, wenn die Funktion zurückkehrt."

Das habe ich mir gedacht. Kann ich die Info auf diese Weise aus der 
Unterroutine irgendwie raus bekommen?

  printf("expandString2: Vorname: %s\n", innen->vor);
  //sollte leer sein
  strcat(innen->vor,"Gabi");
  printf("expandString2: Vorname: %s\n", innen->vor);
  //ich erwarte Gabi und bekomme es auch
  strcat(innen->nach,"Blaubeere");
  printf("expandString2: Vorname: %s\n", innen->vor);
  //ich erwarte Gabi, bekomme aber gabi blaubeere warum
  printf("expandString2: Nachname: %s\n", innen->nach);
  //ich erwarte Blaubeere und bekomme es auch.

Aber warum bekomme ich einmal Gabi Blaubeere statt gabi?

Beitrag melden | Bearbeiten | Löschen |

von moep (Gast)


Angehängte Dateien:

Lesenswert?

Prtobier mal die Lösung im Anhang. Die ist auch noch nicht perfekt,
aber vielleicht mal ein Anfang. Such mal nach "C von A bis Z" bei google

von Peter (Gast)


Lesenswert?

Danke Helfer,
expandStr3 macht alles was es soll. Wie oft wird der Speicher 
reserviert, wenn ich die Funktion 10 mal aufrufe?
/Pepe

von Stefan E. (sternst)


Lesenswert?

> Aber warum bekomme ich einmal Gabi Blaubeere statt gabi?

Weil die Größe (im Sinne von nötiger Speicherplatz) von "Gabi" nicht 4, 
sondern 5 ist, und du die Null-Terminierung überschreibst. Und von 
"Blaubeere" ist die Größe sogar 10 (nicht 7). Und das "Befüllen" mittels 
strcat ist auch ziemlich gefährlich.

> Wie kann ich das lösen

Kommt darauf an, was du eigentlich ganz konkret haben willst. Du 
könntest z.B. in der Funktion ganz simpel schreiben:
1
innen->p_vor = "Gabi";

von Helfer (Gast)


Lesenswert?

Natürlich nur einmal.

von Klaus W. (mfgkw)


Lesenswert?

nein, 10 mal und jeweils am Funktionsende wieder freigegeben bzw. als 
Teil des Stacks für etwas anderes verwendet.

von Peter (Gast)


Lesenswert?

Stefan Ernst schrieb:
> und du die Null-Terminierung überschreibst

Ahh vielen Dank für den Hinweis. Das mit 7 und 10 kam nur wegen eines 
schnell eingefügte namens.
/pepe

von Helfer (Gast)


Lesenswert?

> Natürlich nur einmal.

bezieht sich auf die umgeschriebene Funktion expandStr3 mit

>>  static char vorn[] = {"Gabi"};
>>  static char nachn[] = {"Blaubeere"};

von Klaus W. (mfgkw)


Lesenswert?

ach so, von static hatte ich hier nichts gesehen.

von Peter (Gast)


Lesenswert?

Komisch, wenn ich wie folgt abändere erhalte ich ein komisches Ergebnis:

void expandString2(V_N_Name *innen){
  innen->an = 7;
  innen->av = 4;
  printf("expandString2: Vorname: %s\n", innen->vor);
//    strcat(innen->vor,"Gabi");
  innen->p_vor = "Gabi";
  printf("expandString2: Vorname: %s\n", innen->vor);
//    strcat(innen->nach,"Blaubeere");
  innen->p_nach = "Blaubeere";

  printf("expandString2: Vorname: %s\n", innen->vor);
  printf("expandString2: Nachname: %s\n", innen->nach);
}

Ergebnis:
expandString2: Vorname: ‰ðg
expandString2: Vorname: ‰ðg
expandString2: Vorname: ‰ðg
expandString2: Nachname:

  innen->p_vor = "Gabi";
  innen->p_nach = "Blaubeere";

scheint nicht zu funktionieren.
Warum?

von Stefan E. (sternst)


Lesenswert?

Was genau erwartest du, wenn du innen->p_vor etwas zuweist, aber 
innen->vor ausgibst?

Wie gesagt, es kommt letztlich darauf an, was du überhaupt tatsächlich 
machen willst. Geht es jetzt um die Zeiger in der Struktur, oder die 
char-Arrays? Sind die Strings konstant, oder dynmisch erzeugt? usw.

von Helfer (Gast)


Lesenswert?

Oh Mann, du brauchst wirklich C Grundlagen.

Du kannst nicht nach innen->p_vor zuweisen und dann erwarten, dass du 
aus innen->vor die richtige Ausgabe bekommst. Das eine ist ein Zeiger in 
einer Struktur, das andere ein Feld in einer Struktur. Beide habe exakt 
nix miteinander zu tun, ausser dass sie Mitglied in der gleichen 
Struktur sind.

von Peter (Gast)


Lesenswert?

Vielen Dank,
ich war eben etwas unkonzentriert. Alles was ich ausprobiren wollte 
funktioniert. Vielen Dank für die Unterstützung. Thema kann geschlossen 
werden.
/Pepe

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.