Pro-Linux.de

Pro-Linux

Pro-Linux Diskussions- und Hilfeforum
Aktuelle Zeit: 12. Dez 2018 10:53

Alle Zeiten sind UTC+01:00




Ein neues Thema erstellen  Auf das Thema antworten  [ 5 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Speicher, structs und pointer
BeitragVerfasst: 07. Feb 2006 12:01 
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


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 07. Feb 2006 15:57 
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


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 07. Feb 2006 17:12 
Begehen eigentlich viele C-Programmierer Selbstmord? :lol:

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


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 07. Feb 2006 19:17 
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


Nach oben
   
 Betreff des Beitrags:
BeitragVerfasst: 07. Feb 2006 22:33 
Seltsamerweise tut er trotz -Wall nicht meckern, das benutz ich inzwischen eigentlich immer.

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


Nach oben
   
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen  Auf das Thema antworten  [ 5 Beiträge ] 

Alle Zeiten sind UTC+01:00


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.
Sie dürfen keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
Powered by phpBB® Forum Software © phpBB Limited
Deutsche Übersetzung durch phpBB.de