Problem mit basic_string vector!!! HILFE!
-
Hallo Coders,
Ich weis net mehr weiter, bin hier voll fertig so langsam.
Meinen eigenen Code kann ich leider nicht posten, da er geheim und außerdem sehr groß ist (10000 Zeilen).Folgendes:
Warum wirft mein Programm eine EAccessViolation-Exception wenn ich folgendes tue:
Ich habe eine Funktion, die mir ein void* zurückgibt. Der Zeiger zeigt auf einen mit malloc() allokierten char-Speicherbereich.Bei folgender Zuweisung schmiert mein Programm dann ab (hier natürlich nur skizziert, myOtherFunction() ist die void*-Funktion, die auf meinen ArrayOfChar im Speicher zeigt).
string myFunction() { return (char*) myOtherFunction(); //Exception! }
Die Exception tritt allerdings immer nur dann auf, wenn in dem ArrayOfChar im Speicher ein sehr langer Text steht. Wenn nur 1K z.B. drinsteht, dann klappt es.
Wenn ich folgendes Probiere, wird mein String völlig korrekt und vollständig ausgegeben; Danach jedoch wieder dieselbe Exception:
string myFunction() { char* xxx = (char*) myOtherFunction(); printf("%s\n", xxx); return xxx; //Exception! }
auch ein Versuch wie
string myFunction() { char* xxx = (char*) myOtherFunction(); printf("%s\n", xxx); string verdammte_scheisse = xxx; //Exception! return verdammte_scheisse; }
oder
string myFunction() { char* xxx = (char*) myOtherFunction(); printf("%s\n", xxx); string verdammte_scheisse; verdammte_scheisse.append(xxx); //Exception! return verdammte_scheisse; }
schlägt fehl.
Fazit: Meine Funktion myOtherFunction() funktioniert tadellos und gibt die korrekten Werte zurück; Jedoch schlägt irgendwie, warum auch immer, die Allokierung des basic_strings-Vectors fehl.
Mein Rechner hat insgesamt 768 MB RAM, von denen ca. 200 verwendet werden (d.h. mein Speicher ist NICHT VOLL!).
Ich verstehe echt die Welt nicht mehr. Das geilste ist auch noch, das es in einer anderen Version, wo ich in diesem Fall GAR NICHTS verändert habe, es völlig Problemlos läuft.
Das kann doch nicht wahr sein. Woran kann das bloß liegen???
Ich hoffe, oder besser bete euch an, dass ihr eine Lösung parat habt.
Gruss,
~code_pilot
-
ein Minimal-Beispiel das sich Compilieren lässt erstellen?
-
kannst du... schrieb:
ein Minimal-Beispiel das sich Compilieren lässt erstellen?
Das ist ja gerade daß Problem, ich kann den Fehler auch nicht reproduzieren. Ich weis zwar das es einfacher ist wenn ihr was zum testen habt, aber sowas hab ich leider nicht.
Hier ich hab mal versucht es zu reproduzieren, aber hier funktioniert es dummerweise.
Nur zur Info: Das Beispiel ist Sinnfrei ;)...
#include <condefs.h> #include <conio.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <fstream.h> #include <iostream.h> void* gText = (void*)NULL; void letText(char* text) { if(gText != (void*)NULL) free(gText); gText = (char*)malloc((strlen(text)+1)*sizeof(char)); (void)strcpy((char*)gText, text); } void* getText() { if(gText == (void*)NULL) return (char*)""; return gText; } string getTextValue() { return (char*)getText(); } //--------------------------------------------------------------------------- #pragma argsused int main(int argc, char* argv[]) { FILE* test = fopen("absturz.txt", "rb"); string text; char chr; while(!feof(test)) { chr = fgetc(test); if(chr == '\n') { letText((char*)text.c_str()); printf("%s\n", getTextValue().c_str()); getch(); } else { text += chr; } } fclose(test); return 0; }
Aber ein funktionierendes Beispiel wird auch euch nicht weiterhelfen.
-
Hör mal mit den scheiss Casts auf.
-
Außerdem ist das Beispiel ist fehlerhaft. Man darf doch nicht einfach mit free den Speicher eines std::strings freigeben.
-
hat der string von myotherfunction als letztes zeichen ein \0? ist das worauf der rückgabewert der funktion zeigt überhaupt noch existent wenn das programm aus myOtherFunc rausspringt? da mir ein delete[] fehlt denk ich schonmal, dass es nicht auf dem heap liegt->schau nochmal nach, ob dein char array nicht schon irgendwo zerstört wurde.
//edit und dass du eher c als c++ schreibst, sollte dir wohl klar sein, oder?
-
otze schrieb:
hat der string von myotherfunction als letztes zeichen ein \0? ist das worauf der rückgabewert der funktion zeigt überhaupt noch existent wenn das programm aus myOtherFunc rausspringt? da mir ein delete[] fehlt denk ich schonmal, dass es nicht auf dem heap liegt->schau nochmal nach, ob dein char array nicht schon irgendwo zerstört wurde.
Wenn da kein \0 wäre, dann könnte ich den String auch nicht ausgeben, erst recht nicht direkt wenn ich die Funktion myOtherFunc() aufgerufen habe, und ich kann ja auch sowas machen wie
char* test = myOtherFunc(); printf("%s\n", test); //<- Ausgabe völlig OK! return test; // <- Exception!
otze schrieb:
//edit und dass du eher c als c++ schreibst, sollte dir wohl klar sein, oder?
Das ist mir völlig klar.
Ich programmiere zwar C, benutze jedoch die basic_string Vektoren weil die halt sehr dynamisch und anpassungsfähig sind. Aber bzgl. dieses Problems bin ich doch bei C++ richtig!Gruss,
code_pilot
-
unreg schrieb:
Außerdem ist das Beispiel ist fehlerhaft. Man darf doch nicht einfach mit free den Speicher eines std::strings freigeben.
Ich mache ein free() auf das char*, nicht auf string. Lies mal den Code genauer.
-
Lies du deinen Code mal lieber genauer. Du übergibst letText den internen Speicherbereich einer Variable vom Typ string und löschst ihn da. Das kann nicht gut gehen. Weiterhin kann ich unreg nur zustimmen. Die meisten deiner casts sind völlig unnötig.
z.Bsp. hier:
statt void* gText = (void*)NULL; void* Text = NULL;
oder
(void)strcpy((char*)gText, text);
usw.[edit]Alles zurück. Ich hab mich da wohl verlesen.[/edit]
-
mach doch mal einfacher:
string gText; void letText(const std::string &text) { gText = text; } const string &getTextValue() { return gText; }
-
Braunstein schrieb:
Lies du deinen Code mal lieber genauer. Du übergibst letText den internen Speicherbereich einer Variable vom Typ string und löschst ihn da. Das kann nicht gut gehen. Weiterhin kann ich unreg nur zustimmen. Die meisten deiner casts sind völlig unnötig.
z.Bsp. hier:
statt void* gText = (void*)NULL; void* Text = NULL;
oder
(void)strcpy((char*)gText, text);
usw.Bin ich blind? Wo wird das im o. Code gemacht? Es wird 'gText' geloescht und neu
dafuer Speicher reserviert. Dann wird der Inhalt von 'text' in 'gText' _kopiert_.mfg
v R
-
Ok hast Recht.
Aber das hier:void* getText() { if(gText == (void*)NULL) return (char*)""; return gText; }
müsste doch Schwierigkeiten machen wenn gText NULL ist. Immerhin gibt er hier einen Pointer auf ein lokales konstantes Stringliteral zurück. Oder wird bei einem Leerstring ein NULL-Pointer übergeben?
-
Braunstein schrieb:
Ok hast Recht.
Aber das hier:void* getText() { if(gText == (void*)NULL) return (char*)""; return gText; }
müsste doch Schwierigkeiten machen wenn gText NULL ist. Immerhin gibt er hier einen Pointer auf ein lokales konstantes Stringliteral zurück. Oder wird bei einem Leerstring ein NULL-Pointer übergeben?
stringliterale existieren auch nach dem verlassen einer funktion. das verursacht hier also keine probleme.
-
Hallo!
Hmmm ich bin dem Problem etwas näher gekommen: Es sieht so aus, als ob der String-Vector ganz einfach sich Speicher reserviert, der schon einem anderen Pointer "gehört". Ich weis auch nicht WIE der da hinkommt, nur steht bei mir in einem völlig anderem char-Pointer (nich im obigen Beispiel erkennbar!) auf einmal genau 600 Byte aus dem Text (3560 Byte insgesamt, es werden aber nur 2960 Byte verwendet, der Rest steht auf einmal da wo er nicht stehen soll!!!).
Dazu sei noch zu sagen, dass ich genau 3560 + 1 Byte zuvor für diesen Text reserviere, und in dann mit strcpy() in den Speicher reinschreibe...
Ich verwende zur Allokierung immer malloc(). Liegt's vielleicht daran?
Und wenn ich versuche, meine "myOtherFunc()" als static void* zu deklarieren, meckern mein Compiler rum, er würde die Funktion nirgendwo finden.Warscheinlich weil sie dann static ist.
Aber das kann's ja auch nicht sein.
Gruss,
cp
-
ssm schrieb:
string gText; void letText(const std::string &text) { gText = text; } const string &getTextValue() { return gText; }
Was bezweckt denn das genau??
Weil der C++Builder bisher nie gemecker hat. Brauche ich evtl auch dieses "namespace std;" ??Aber ich denke mal nicht das es daran liegen wird.
Gruss,
~code_pilot
-
code_pilot schrieb:
Was bezweckt denn das genau??
Weil der C++Builder bisher nie gemecker hat. Brauche ich evtl auch dieses "namespace std;" ??[cpp]
**#include <string>
using std::string;**
string gText;
void letText(const string &text)
{
gText = text;
}const string &getTextValue()
{
return gText;
} [/cpp]
-
jo wie gesagt: Es bringt nix
.
-
code_pilot schrieb:
jo wie gesagt: Es bringt nix
.
Fehler?
-
hast du schon mal versucht, die exception abzufangen, um herauszubekommen, worum es sich handelt? durch einsatz eines debuggers kommt man dem problem in der regel auch auf die spur, wenn es reproduzierbar ist.
-
wenn du auf C++ schreiben will, wieso nicht einfach so:
#include <string> #include <iostream> #include <fstream> std::string gText; void letText(const std::string &text) { gText = text; } const std::string &getTextValue() { return gText; } int main(int argc, char* argv[]) { std::ifstream is("absturz.txt"); std::string line; while(is && std::getline(is, line)) { letText(line); std::cout << getTextValue(); //getch(); } }
für CBuilder gibt's eigentlich ein anderes Forum