seltsames String-Handling C++

theton

theton

Bitmuncher
Ich habe weniger ein Problem (bzw. ist selbiges bereits geloest), als eher mal eine Frage, die mir vielleicht hier jemand beantworten kann. Bei folgendem Code bekomme ich einen Buffer-Overflow und mir ist absolut nicht klar, wodurch dieser ausgeloest wird.

Code:
...
std::string mfilename; // die einzulesende Datei
std::string filedata; // der Inhalt der Datei
char *message; // hier brauchen wir den Datei-Inhalt
std::ifstream file(mfilename.c_str(), std::ios::binary | std::ios::in);
if(!file) {
  std::cerr << "Couldn't open message file!" << std::endl;
  exit(1);
}
/* Inhalt der Datei einlesen */
char c = file.get();
for( ; file.good(); c=file.get()) {
  if(file.bad()) {
    break;
  }
  filedata.push_back(c);
}
strcpy(message, filedata.c_str()); // hier wird der Zugriffsfehler ausgeloest
...
Was der Code tun soll, duerfte ja klar sein... Datei oeffnen -> Inhalt einlesen -> Inhalt fuer die weitere Verarbeitung in message ablegen. message muss vom Datentyp 'char *' sein, da bei der Weiterverarbeitung Funktionen genutzt werden, die aus der C-Bibliothek stammen und da sie eben fuer C sind, koennen sie nicht mit String-Klassen umgehen.
Mir ist nun nur nicht klar, warum ein Speicherzugriffsfehler beim strcpy() ausgeloest wird. Selbst wenn ich mit strncpy() nur die ersten 5 Zeichen genommen habe, kam es zu einem Zugriffsfehler und auch eine Initialisierung von message am Anfang der Funktion mit einem festen Wert brachte keine Abhilfe. Die schaffte uebrigens ein simples
Code:
message = filedata.c_str();
Und ja, mir ist klar, dass strcpy() auch nicht aus der C++-Bibliothek ist, aber ich bin nunmal daran gewoehnt und bin dadurch auf diesen seltsamen Fehler gestossen, der mir nun einiges Kopfzerbrechen bereitet. :)

Nachtrag: Ganz vergessen... g++ (GCC) 3.3.5 (Debian 1:3.3.5-13) :)
 
Zuletzt bearbeitet:
Theton schrieb:
char *message; // hier brauchen wir den Datei-Inhalt

Ohne klugscheißen zu wollen, aber wenn Du den Inhalt einer ASCII kodierten Datei an einen Zeiger auf eine Zeichenkette übergibst, musst Du auch den Speicherbereich auf den er zeigt, und in dem die Daten landen auch noch allozieren.


Bei strenger C-Notation wäre das dann so etwas:
Code:
char* message = (char*) malloc(size_of(file.get()+1));  // fuer das sz
bzw. bei Verwedung von C++-Konstrukten:
Code:
char* message = new char[strlen(file.get()+1)];  // fuer das sz


Funktionsfähig ist:
Code:
message = filedata.c_str();

deshlab, weil du mit diesem Aufruf den Zeiger (message) auf einen bereits allozierten Speicherbereich richtest, nämlich den
der von INSTANCE.c_str() als ein Bezeichner vom Typ: Zeiger auf char* alloziert wurde.

...aber vielleicht red' ich mich ja auch grad um Kopf und Kragen :)
 
Zuletzt bearbeitet:
theton schrieb:
Und ja, mir ist klar, dass strcpy() auch nicht aus der C++-Bibliothek ist, aber ich bin nunmal daran gewoehnt und bin dadurch auf diesen seltsamen Fehler gestossen, der mir nun einiges Kopfzerbrechen bereitet. :)

Du bist daran gewoehnt? Dann gewoehn Dich mal besser ganz schnell um:
man strcpy schrieb:
The strcpy() function copies the string pointed to by src (including
the terminating `\0' character) to the array pointed to by dest. The
strings may not overlap, and the destination string dest must be large
enough to receive the copy.
Mit Betonung auf dem letzten Satz!
Ausserdem sollte man strcpy vermeiden und strncpy benutzen.

Oder eben gleich c++ benutzen. Da Du die Daten schon in einem std::string hast, wieso moechtest Du sie ueberhaupt noch in einen char* umwandeln?
 
@rikola Wie ich bereits sagte, kam der Zugriffsfehler auch bei strncpy() selbst wenn ich nur die ersten 5 Zeichen genutzt habe. Hat also garnichts bewirkt. Die Manpage zu strcpy kenne ich selbst. Warum ich die Daten in einem char * haben will, habe ich auch bereits erklaert.

@x0r: Klinkt logisch. Mein Fehldenken war hier wohl, dass ich davon aus ging, dass fuer char * der Speicher dynamisch alloziert wird. Beim naechsten Mal also allozieren nicht vergessen. :)
 

Ähnliche Themen

g++ kompilieren schlägt fehl

[C++] Socket Probleme mit Adresse...

2 WAV Dateien gleichzeitig abspielen + SDL

Zurück
Oben