Unerwartetes Verhalten von strcpy()



  • Hi
    Ich sitze hier gerade auf einem Problem fest, dessen Ursprung ich nicht genau lokalisieren kann.
    Gegeben sei eine Funktion welche eine Datei löschen soll.

    void DeleteFile()
    {
    char szTest[255];
    int i;
    strcpy(szTest,"foo");
    i = remove("test.txt");
    return;
    }
    

    Führe ich nun diese Funktion mit aktiven Debugger aus. Sehe ich folgendes:
    - Vor der Aushführung von strcpy zeigt die Zeichenkette szTest auf einen bestimmten Speicherbereich X
    - Nach der Ausführung von strcpy ist diese Adresse um genau 268 Bytes nach vorne verschoben worden.
    - Genau diese 268 Bytes später ist auch die Zeichenkette reingeschrieben worden.
    - Alles was danach kommt ist rein zufällig. Entweder bleibt der Zeiger auf dieser neuen Adresse konstant für den gesammten Gültigkeitsbereich der Funktion bestehen, oder er geht wieder auf seinen Ursprünglichen Wert zurück. Alle wunderbar reproduzierbar. Übergebe ich z.B. als source für strcpy einen pointer auf eine gültige 0-terminierte Zeichenkette so ändert sich der Zeiger auf den ursprünglichen Wert.

    Warum es mir geht? Ich verstehe dieses Verhalten nicht. Ich habe versucht das eigentliche Problem dass ich hatte auf das Grundproblem zu reduzieren und dass ist dabei rausgekommen. Ich suche also keine Lösung sondern eine Erklärung für dieses Verhalten.
    Verwendeter Compiler ist VC++ 2003

    mfg Sven



  • Dein Array szTest ist nicht initialisiert, also könnte es sein, dass es nicht '\0'-terminiert ist, also nicht korrekt von strcpy() verarbeitet werden kann. Um dies zu korrigieren, initialisiere das Array mit "\0". Hoffentlich hilft dies.



  • @ISO-C User: Quatsch mit Soße!
    @sgergen: kann's mir nicht erklären - bei Geistesblitz meld ich mich.

    Greetz, Swordfish



  • Ich habe die Zeichenkette nun mal mit 0 initialisiert. Intressanterweise verhält sich das Programm dann absolut korrekt. Der Zeiger der auf die Zeichenkette zeigt bleibt die ganze Zeit unverändert.
    Diese Funktion, sollte ich dabei noch erwähnen, ist in ein etwas größeres Programm eingebettet. Mittlerweile habe ich in einem neuen Projekt welches nur aus dieser Funktion bestand versucht das Verhalten zu rekonstruieren. Intressanterweise war dies dort nicht möglich. Da aber keinerlei weitere Funktionen aus eben diesem Programm aufgerufen werden, kann ich mich nicht erklären dass diese darauf einwirken könnten. Könnte möglicherweise der Stack durch vorherige Operationen verstümmelt worden sein?
    Da strcpy die Länge des source eigentlich egal ist, kann ich nicht glauben ihm eine vorinitialisierte Zeichenkette übergeben zu müssen.

    Sven



  • hi, du musst das ganze mal im asm-code durchsteppen, dann siehste was da wirklich passiert. source code debuggern kann man nicht immer trauen.
    ääh...szTest ist übrigens kein zeiger, also da sollte sich eigentlich nichts verändern



  • Hi
    das mit dem ASM-Code habe ich befürchtet. Dummerweise liegen meine Assemblererfahrungen schon recht weit zurück und ausser mov ist mir nichts mehr im Sinn 🙂
    Mal kucken ob ich trotzdem was rausfinde.

    mfg Sven

    P.S. szTest habe ich des öfteren als Zeiger benannt, auch wenn dies natürlich nicht ganz richtig ist, schließlich wird strcpy ja nur die Adresse der Zeichenkette übergeben, womit folgich strcpy keinen Zugriff auf die Basisadresse von szTest hat.



  • vielleicht zeigt dein debugger es richtiger an, wenn sich szTest nicht auf'm stack befindet. nimm doch szTest mal aus der funktion raus (d.h. schreibs über den funktionskopf)



  • @net:
    ok. Assemblercode schrittweise durchlaufen und festgestellt das es zu lange her ist. Keine Ahnung was der ausgeführte Assemblercode bewirkt.
    Die Variable habe ich nun global definiert. Das Verhalten dann ist absolut korrekt, und es treten keine Probleme auf.
    Was mich wieder zum grübeln bringt, wer der schuldige ist. Die Ausgangssituation dafür war folgendes:
    Ursprünglich wurde remove als parameter direkt eine Funktion übergeben die einen Zeiger auf einen global existierende 0-terminierte Zeichenkette zurückgibt. Das löschen dieser Datei funktionierte nie. Da ich diesen Paramter nicht direkt mit dem Debugger auswerten konnte, ging ich den Zwischenschritt, diese Zeichnkette erst in eine lokale zu kopieren und sie dann zu übergeben. Dabei fiel mir dieses für mich nicht erklärliche Verhalten auf.
    Wie gesagt, ich kann machen das das ganze funktioniert, allerdings besteht mein Interesse daran zu kapieren, warum er sich so verhielt, um nicht irgendwann größere Probleme zu bekommen.

    Sven



  • naja, ich geh mal davon aus, dass der debugger mist anzeigt. vielleicht hast du irgendwelche codeoptimierungen aktiviert, mit denen der debugger nicht klar kommt. eigentlich ist der visual studio debugger recht gut und ich kenne solche macken nicht von ihm, aber, wer weiss schon wirklich, wieviele versteckte bugs auch der hat...


Anmelden zum Antworten