Hinweis: Das Forum wird geschlossen! Neue Registrierungen sind nicht mehr möglich!

 Zurück zu Pro-Linux   Foren-Übersicht   FAQ     Suchen    Mitgliederliste
Speicher, structs und pointer

 
Neuen Beitrag schreiben   Auf Beitrag antworten    Pro-Linux Foren-Übersicht -> Programmieren - C
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Tim_
Gast





BeitragVerfasst am: 07. Feb 2006 12:01   Titel: Speicher, structs und pointer

Ich stehe hier vor einem kleinen Problem mit structs und pointern.
Folgendes funktioniert einwandfrei:
Code:

struct foo
{
   char *c1;
};

int main()
{
   struct foo bar;
   bar.c1 = (char *)malloc(6);
   bar.c1 = "blubb";
   
   printf("%s\n", bar.c1);

   return 0;
}


Wohingegen
Code:

struct foo
{
   char *c1;
};

int main()
{
   struct foo *bar;
   bar->c1 = (char *)malloc(6);
   bar->c1 = "blubb";
   
   printf("%s\n", bar->c1);
   
   return 0;
}

einen Segmentation fault zur Folge hat.
Vermutlich ist es was triviales aber ich hab bisher keine Lösung gefunden.

Wäre super wenn mir jemand den Tipp geben könnte was ich hier falsch mache.

Gruß & danke
Tim
 

Alex.MH
Gast





BeitragVerfasst am: 07. Feb 2006 15:57   Titel:

Hi,

zu Beispiel 1:
Hier kannst du dir das malloc sparen. "blubb" wird nicht, wie du vielleicht denkst, in den frisch allozierten Speicher geschrieben. Du musst schon sowas wie "strncpy()" verwenden, um "blubb" in deinen neuen Speicherbereich zu schreiben. Eigentlich sollte der Compiler eine Warnung ausgeben, dass du einem char pointer einen "const char" Wert zuweisen willst. Dein Speicher, den du malloc alloziert hast geht in dem Moment verloren, indem du dem char pointer die Adresse von "blubb" zuweist. Dein Programm wuerde in diesem Fall ein Speicherleck haben, da du den allozierten Speicher nicht mehr freigeben kannst (du hast ihn ja mit einem neuen Pointer ueberschrieben).

zu Beispiel 2:
Es funktioniert nicht, weil du keine Speicher fuer die Struktur "bar" allozierst. Mit "struct foo *bar" hast du einen Pointer auf eine Struktur. Dieser Pointer zeigt aber ins Nichts. Greifst du dann darauf zu erhaelst du einen Segmentation Fault. Du musst mit "malloc()" erst Speicher fuer die Struktur allozieren und dann kannst du auf die Variablen der Struktur zugreifen.
Dein Beispiel 1 funktioniert, weil hier der Compiler fuer dich den Speicher fuer bar reserviert.

Gruss,
Alex
 

Tim_
Gast





BeitragVerfasst am: 07. Feb 2006 17:12   Titel:

Begehen eigentlich viele C-Programmierer Selbstmord? Laughing

Danke, im Nachhinein ist es nicht ganz unlogisch dass man für das struct den Speicher reserviert und nicht für die einzelnen Variablen, aber von alleine wär ich da nicht draufgekommen.

Bei dem ersten Beispiel gibt er mir keinerlei Warnungen aus (gcc Gentoo 3.3.6).
Heisst das also, dass jede Zuweisung wie
c = "whatever";
den String zwischen den " neu in den Speicher schreibt und diese Adresse dem Pointer dann zuweist?
Und beim ersten Beispiel reserviert der Compiler für 'bar' einen Speicherbereich der Größe sizeof(char *) und nicht Platz für die chars selbst?!
Ist das denn dann so in Ordnung oder würde man das irgendwie anders machen?
Sprich, sollte ich im zweiten Beispiel dann für den Pointer auf das struct 4 Byte (=sizeof(char *)) oder 4 + x Bytes reservieren wenn ich x chars speichern will?

Was ist der saubere Weg?

Vielen Dank
Tim
 

Alex.MH
Gast





BeitragVerfasst am: 07. Feb 2006 19:17   Titel:

Zitat:

Bei dem ersten Beispiel gibt er mir keinerlei Warnungen aus (gcc Gentoo 3.3.6).


Kompilier deine Sachen einfach mit "-Wall" - dann warnt dich der Compiler. Sollte man eh immer machen.

Zitat:

Heisst das also, dass jede Zuweisung wie
c = "whatever";
den String zwischen den " neu in den Speicher schreibt und diese Adresse dem Pointer dann zuweist?


Ganz genau. "whatever" ist dann aber vom Typ "const char*" und darf somit nicht veraendert werden. Deshalb sollte dich der Compiler auch warnen, denn wenn du versuchst "whatever" mit einem String gleicher laenge zu ueberschreiben, dann stuerzt dein Programm mit einem "bus error" ab.

Sauberer Stil ist es also Konstanten auch als const zu markieren:
Code:

const char* c = "whatever";


Zitat:

Und beim ersten Beispiel reserviert der Compiler für 'bar' einen Speicherbereich der Größe sizeof(char *) und nicht Platz für die chars selbst?!


Ebenfalls richtig. Allerdings reserviert der Compiler nicht sizeof(char*) sondern sizeof(struct foo) - was in diesem Fall aber das gleiche ist.

Zitat:

Ist das denn dann so in Ordnung oder würde man das irgendwie anders machen?
Sprich, sollte ich im zweiten Beispiel dann für den Pointer auf das struct 4 Byte (=sizeof(char *)) oder 4 + x Bytes reservieren wenn ich x chars speichern will?


Korrekt sollte das zweite Beispiel so aus sehen (ungetestet - also vielleicht doch nicht ganz korrekt):
Code:

int main()
{
    struct foo* bar = (struct foo*)malloc(sizeof(struct foo));

    bar->c1 = (char*)malloc(6 * sizeof(char));

   strncpy(bar->c1, "Hallo", 6);

   printf("%s\n", bar->c1);

   return (0);
}


Gruss,
Alex
 

Tim_
Gast





BeitragVerfasst am: 07. Feb 2006 22:33   Titel:

Seltsamerweise tut er trotz -Wall nicht meckern, das benutz ich inzwischen eigentlich immer.

Wieder mal danke für die Hilfe!
Gruß
Tim
 

Beiträge vom vorherigen Thema anzeigen:   
     Pro-Linux Foren-Übersicht -> Programmieren - C Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehen Sie zu:  

Powered by phpBB © phpBB Group
pro_linux Theme © 2004 by Mandaxy