Deklaration von char Zeigern ( String)



  • Hi zusammen, ich habe ein Verständnisproblem beim Deklarieren von Zeigern des Typs
    char.
    Wenn ich einen einen Zeiger folgendermassen deklariere:
    Methode 1:

    char *spalten_trenner = ",";
    

    zeigt mir der Debugger ddd (Linux) folgende Ausgabe an:
    (gdb) print spalten_trenner
    $2 = 0x10000898 ","

    Deklariere ich den Zeiger aber so:
    Methode 2:

    char zeilen_trenner[] = ";";
    

    gibt der Debugger folgendes aus:

    (gdb) print zeilen_trenner
    $1 = ";"

    Meine Frage ist jetzt, warum ich bei der ersten Methode eine Hex-Zahl mit ausgegeben bekomme und bei der zweiten nicht, da ich bis dato immer dachte, dass die beiden Deklarationen identisch sind.

    Auf das Problem bin ich gestossen, als ich der Library-Funktion strtok() einen char Zeiger mit der ersten Deklaration uebergeben habe. Die Funktion strtok() hat daraufhin eine Speicherzugriffsverletzung verursacht. Gehe ich nach der zweiten Methode vor funktioniert die Funktion korrekt.

    Gruss Amtrak



  • Mit Zeiger schreibt der Compiler zwecks Optimierung meist in Readonly-Speicher.
    Wenn du dadrauf schreibenderweise zugreifen willst, ist ja klar dass nichts Gescheites bei rauskommt 😃
    Wie rufst du denn strtok() auf?!

    Mit Methode 2 deklarierst du übrigens keinen Zeiger, sondern ein Array mit der Größe 2 (";\0"). Bei erster Methode dürfte die Hexzahl die Adresse des Speichers sein, auf die der Zeiger zeigt, bin mir aber nicht ganz sicher...

    [ Dieser Beitrag wurde am 12.06.2003 um 23:43 Uhr von RTC editiert. ]



  • die Funktion strtok() rufe ich folgendermassen auf:

    char *buf="1 2 3 4; 4 5 6 7 8";
    char *del=";";
    char *s=NULL;
    
    int main(void){
    
    for (s=strtok(buf,del);s;s=strtok(NULL,del)){
          printf("%s\n",s);
          }
    return 0;
    }
    

    Ich nehme mal an, dass du mit Readonly-Speicher das Data-Segment des Speicherbereichs eines Prozesses meinst, da dort alle globalen vorbesetzen Deklarationen abgelegt werden.Allerdings ist der nicht Readonly, da man dann die Variablen nicht mehr verändern koennte. 😃

    Leider hilft mir das nicht bei meinem Problem zu verstehen, warum die die Hex-Zahl(Speicherstelle ??) mit angegeben wird.

    Trotzdem danke



  • Original erstellt von Amtrak:
    **die Funktion strtok() rufe ich folgendermassen auf:

    char *buf="1 2 3 4; 4 5 6 7 8";
    char *del=";";
    char *s=NULL;
    
    int main(void){
    for (s=strtok(buf,del);s;s=strtok(NULL,del)){
          printf("%s\n",s);
          }
    return 0;
    }
    

    **

    Kann nicht klappen, da du versuchst den Rückgabewert von strtok() in einem Zeiger auf char zu speichern. Für diesen Zeiger hast du aber noch gar keinen Speicherplatz reserviert, somit MUSS es zum Speicherzugriffsfehler kommen!
    Um das zu lösen, würde ich dir empfehlen, ein char-Array zu deklarieren sagen wir mit 1000 Elementen, sodass der Teilstring auch genug Platz hat und dann mit s=malloc(strlen(chararray)) Speicher für den char-Zeiger zu reservieren, vorausgesetzt du speicherst mehrere Teilstrings, womit durch die dynamische Speicherallozierung kein Speicher verschwendet wird.

    Original erstellt von Amtrak:
    Ich nehme mal an, dass du mit Readonly-Speicher das Data-Segment des Speicherbereichs eines Prozesses meinst, da dort alle globalen vorbesetzen Deklarationen abgelegt werden.Allerdings ist der nicht Readonly, da man dann die Variablen nicht mehr verändern koennte. 😃

    Nope. AFAIK gibt es auch im RAM einen RO-Speicher, in den ein Compiler aus Optimierungsgründen RO-Variablen schreibt. Bin mir jetzt aber auch nicht ganz sicher, auf alle Fälle ist das das Problem, wenn du auf einen per *z="bla"; initialisierten Zeiger schreibend zugreifen willst.

    Original erstellt von Amtrak:
    **
    Leider hilft mir das nicht bei meinem Problem zu verstehen, warum die die Hex-Zahl(Speicherstelle ??) mit angegeben wird.**

    Hab ich schon im ersten Reply geschrieben: ich bin mir fast sicher, dass dies die RO-Speicheradresse ist, auf die der Zeiger zeigt. Im zweiten Fall initialisierst du ein Array, das ist etwas Grundverschiedenes wie Zeiger (obwohl es natürlich Parallelen gibt, so ist der Arrayname ein konstanter Zeiger und auf alle Arrayelemente kann man auch mittels Zeigern zugreifen).

    Hoffe, das reicht dir als Antwort. Wegen dem GDB würde ich mal in den HOWTOs nachschauen oder googlen 😃



  • Noe, du benoetigst keinen Speicher fuer s. Spaetestens nach

    s = strtok ( ... );
    

    haettest du dann ein mem leak, da 's' jetzt auf den im ersten Parameter gefundenen
    Token zeigt (oder NULL, falls nichts gefunden wurde) und es keinen Bezug mehr
    zum reservierten Speicher gibt.

    Uebrigens, laeuft dein Prog bei mir ohne Probleme.

    mfg
    v R



  • @RTC

    Nope. AFAIK gibt es auch im RAM einen RO-Speicher, in den ein Compiler aus Optimierungsgründen RO-Variablen schreibt. Bin mir jetzt aber auch nicht ganz sicher, auf alle Fälle ist das das Problem, wenn du auf einen per *z="bla"; initialisierten Zeiger schreibend zugreifen willst.

    Hast du fuer diese Aussage eine Quelle in der man das mal nachlesen kann, da ich davon noch nie gehoert habe. Nicht das ich dir nicht glaube, wuerde es nur gerne mal im Zusammenhang lesen 😃 .

    @virtuell Realisticer
    das mit dem Speicher fuer s sehe ich genauso, da die Funktion strtok() einen Zeiger auf den gefundenen Teilstring zurueck gibt und keinen ganzen String.

    Da das Progamm bei dir laeuft muss ich wohl noch mal auf Fehlersuche gehen 😞
    Ich nehme mal an, das du es auf einer x86 Plattform compiliert hast. Ich hatte den Quelltext auf einem mac compiliert, vielleicht liegt es daran. Werde das so bald wie möglich testen

    Gruss Amtrak



  • Original erstellt von RTC:
    [quote]Original erstellt von Amtrak:
    [qb]Ich nehme mal an, dass du mit Readonly-Speicher das Data-Segment des Speicherbereichs eines Prozesses meinst, da dort alle globalen vorbesetzen Deklarationen abgelegt werden.Allerdings ist der nicht Readonly, da man dann die Variablen nicht mehr verändern koennte. 😃

    Nope. AFAIK gibt es auch im RAM einen RO-Speicher, in den ein Compiler aus Optimierungsgründen RO-Variablen schreibt. Bin mir jetzt aber auch nicht ganz sicher, auf alle Fälle ist das das Problem, wenn du auf einen per *z="bla"; initialisierten Zeiger schreibend zugreifen willst.
    [/qb][/quote]
    Nein, einen RO-Speicher für sowas gibt es definitiv nicht (zuminest ind en Architekturen x86 und Sparc). Wie sollen denn sonst die Daten da reinkommen 😉 Allerdings kann der Prozessor bestimmte Speicherblöcke als read-only markieren. Und das kann Ärger geben, wenn man da versucht zu schrieben.



  • Gott, nu war ich aber ganz verpeilt. Hast natürlich recht @vr! 🙄


Anmelden zum Antworten