Inhalt eines Char-Zeigers einem String zuweisen
-
Hallo,
ich weiß solche Beiträge findet man bei Google haufenweise, nur haben mir die dort beschriebenen Methoden nicht geholfen mein Problem zu lösen, und zwar folgendes:
Ich habe einen Zeiger angelegt, der auf einen Speicher im Heap zeigt:char *p_char = new char [1025];Nun wird der Zeiger einer Funktion übergeben und diese verändert den Wert, ein anschließendes
cout << "p_char: " << p_char << endl;zeigt mir den korrekten Wert des Arrays an. Wenn ich nun allerdings versuche, diesen Wert einer map<string,string> zuzuweisen mit:
mapDrv["p_char"] = p_char;bekomme ich bei der Ausführung des Programms an dieser Stelle einen Speicherfehler. Kann mir jemand sagen, wie ich die Zuweisung gestalten muss, damit es korrekt funktioniert?
mfg chuqa
-
zeig doch mal mehr code bitte, denn bei mir funktioniert es.
-
da gibt es eigentlich nicht viel mehr zu zeigen ich poste mal den original Quelltext:
char *innerClass = new char [FC6_MAX_NAME_LEN +1]; innerClass[0] = '\0'; fcInnerClassRef(innerClass, p_c, "_ParamList", "paramlist"); cout << "innerClass: " << innerClass << endl; ref_mapDrv["ifaceParamClass"] = innerClass; free(innerClass);Mehr ist es eigentlich nicht. Wenn ich mit dem gdb-debugger an die Stelle der Zuweisung komme und mir den Wert von innerClass ausgeben lasse, steht dort ebenfalls der korrekte Wert in der Variablen, nur beim nächsten Schritte tritt der Fehler auf, ist beim gdb ein Segmentation fault.
mfg chuqa
-
AAAHHH, niemals free auf new allokierten Speicher!!!
--- free(innerClass); +++ delete[] innerClass;/edit Wieso benutzt du hier eigentlich keine Strings?!
-
Ok danke für den Tipp der Speicherfreigabe.
Strings gehen nicht, da ich auf Funktionen zugreife, die ich nicht zu verantworten habe und die char-Zeiger erwarten.
mfg chuqa
-
Also irgendwie hab ich eigentlich nix gemacht, trotzdem tritt der Fehler jetzt nichtmehr an der Stelle der Zuweisung an die Map auf sondern schon beim ersten Lesen der Variable innerClass nach der Funktion. In der Funktion passiert mit der Variable eigentlich nix anderes als eine Wertzuweisung, die auch erfolgreich ist:
int fcInnerClassRef(char *target, char *p_outerClass, char *baseName, char *member){ ... strncpy((char*)target, p_innerClass, FC6_MAX_NAME_LEN); cout << "target: " << target << endl; return 0; }Und genau der erste Aufruf von innerClass funktioniert nicht, auch wenn ich an der Stelle des Aufrufs mir den Wert von der Variable mit dem Debugger ausgeben lasse, kommt nur
$1 = 0x0
. Also irgendwie wird der Wert dort nicht zugewiesen.
-
Verwende bitt string in einer map. Wenn andere Funktionen char* brauchen, mußt du eben wieder umwandeln (mit c_str() oder kopieren).
Sowas hierref_mapDrv["ifaceParamClass"] = innerClass; free(innerClass);ist tödlich. Selbst wenn statt free hier delete[] steht wird der Pointer in der map ungültig und jeder weitere Zugriff erzeugt undefieniertes Verhalten.
-
Chuqa schrieb:
... diesen Wert einer map<string,string> zuzuweisen
Er benutzt std::string in der Map, also wird korrekt (=tief) kopiert.
Chuqa schrieb:
int fcInnerClassRef(char *target, char *p_outerClass, char *baseName, char *member){ ... strncpy((char*)target, p_innerClass, FC6_MAX_NAME_LEN); cout << "target: " << target << endl; return 0; }Der Code ist, soweit ich das sehe richtig. Schau mal, wo target den Nullzeiger zugewiesen bekommt. (Und mehr Code ...)
-
Also habe mal alle delete entfernt, hatte auch zu Testzwecken innerClass als string deklariert und eine Referenz auf diesen String der Funktion fcInnerClassRef übergeben, passiert aber genau das gleiche.
Ich weise target nirgends den Nullzeiger zu, deklariere innerClass als char-Zeiger und übergebe ihn der Funktion fcInnerClassRef();
Mehr Code gibt es einfach nicht, der die Variablen betrifft. Ich deklariere das Array im Heap, übergeben einen Zeiger auf das Array an die Funktion, dort wird der Wert verändert (die Ausgabe von target in der Funktion ist korrekt) und versuche nach Verlassen der Funktion erneut auf den Zeiger zuzugreifen, welches mir ein Memory fault liefert.int fcInnerClassRef(char *target, char *p_outerClass, char *baseName, char *member){ ... strncpy((char*)target, p_innerClass, FC6_MAX_NAME_LEN); cout << "target: " << target << endl; return 0; } void installIface(map<string, string> &ref_mapDrv, // g map<string, string> &ref_mapParams, // driverparam &ref_drvParam, // driverparam &ref_param_parseParaDef, // baseInterface &ref_baseIface) // dp { ... char *innerClass = new char [FC6_MAX_NAME_LEN +1]; innerClass[0] = '\0'; fcInnerClassRef(innerClass, p_c, "_ParamList", "paramlist"); cout << "innerClassRef: " << innerClass << endl; // FEHLER ... }Das ist eigentlich alles, wenn du etwas bestimmtes noch haben möchtest, sage bescheid.
mfg chuqa
-
Woher kommt denn die Variable p_innerClass die in der Funktion kopiert wird? Ist diese vielleicht zu lang, so dass FC6_MAX_BLA nicht reicht, oder nicht initialisiert, oder nicht nullterminiert, oder...?
Du siehst, es war nicht alles relevante dabei

-
Dafür ist doch strncpy da, oder? Aber der Zeiger scheint ja laut Debugger den Wert 0 zu haben (oder ist das der dereferenzierte Zeiger?!). Wird innerhalb des ominösen ...-Bereichs noch in irgendeiner Art und Weise auf den Zeiger zugegriffen?
-
Hups, habe dieses kleine n doch glatt übersehen

-
Nein auf den Zeiger wird vorher nicht zugegriffen, das ist der erste Zugriff. Leider sind meine Erfahrungen mit Zeiger sehr begrenzt, deswegen hoff ich auf eure Hilfe.
-
Vielleicht wäre es besser, den kompletten Code von fcInnerClassRef anzugeben.
Was soll übrigens dieser char*-Cast von Target in dieser Funktion?
-
Was der Typecast sollte, weiß ich auch nicht, ändert nur leider nix am Fehler. Also wenn ich die Funktion poste, muss ich das halbe Programm vermutlich dazu posten, welches im Moment ca. 2000 Zeilen umfasst. Und dann darf ich das leider nicht, denn das was ich hier schreibe ist für meinen Praxispartner und deswegen Eigentum von ihm. p_innerClass ist auch ein Array, welches im Heap liegt und die gleiche Größe wie bereits innerClass hat. Die Werte die in den Arrays geschrieben werden, sind aber deutlich kleiner als als die definierte Größe.
Was eben mich nur wundert,ist,dass target den korrekten Wert hat und innerClass nicht, dabei sind das doch dieselben Variablen, oder nicht?
-
Es dreht sich hier erstmal bloß um fcInnerClassRef. Falls da irgendwo vorher target auf 0 gestzt wird, oder eine lokale Variable namens target den Parameter überdeckt kann sowas auftrteten. Geh doch mal mit deinem Debugger durch und schau dir target an.
-
So bin grad das Programm mit einem Debugger durchgegangen und habe mir die betroffene Variable angeschaut. Ich poste mal die Ausgaben und die Stellen im Quellcode(mit p <variable> kann ich mir den Wert der Variablen ausgeben lassen):
/* Bei Aufruf von fcInnerClassRef()
fcInnerClassRef(innerClass, p_c, "_ParamList", "paramlist");
p innerClass */
$17 = 0x81c5c90 ""
/* in fcInnerClassRef unmittelbar zu Beginn
p target */
$18 = 0x81c5c90 ""
/* unmittelbar vor strncpy
strncpy(p_target, p_innerClass, FC6_MAX_NAME_LEN);
p target */
$20 = 0x81c5c90 "
/* unmittelbar nach strncpy */
strncpy(p_target, p_innerClass, FC6_MAX_NAME_LEN);
p target */
$21 = 0x81c5c90 "/fc6demo.Devices.Classes._ParamList._ParamList0x0000010C"
/* bei return aus fcInnerClassRef
p target */
$22 = 0x81c5c90 "/fc6demo.Devices.Classes._ParamList._ParamList0x0000010C"
/* unmittelbar nach verlassen von fcInnerClassRef() in installIface()
p innerClass */
$23 = 0x0also so wie es aussieht wird dem Zeiger innerClass nach Verlassen der Funktion der Nullzeiger zugewiesen, aber warum?
-
Hmm, wer hat denn noch alles Zugriff auf innerClass? Vielleicht gibts irgendeinen Destruktor, der das zurücksetzt. Wir brauchen mehr Code. Zeig mal welche Objekte in fcInnerClassRef deklariert werden.
-
char *baseNameCnt = new char [FC6_MAX_NAME_LEN+1]; char *p_nn = new char [100]; int nn; char *p_innerClass = new char [FC6_MAX_NAME_LEN +1]; char c_nn [20]; char *p_innerClassGroup = new char [FC6_MAX_NAME_LEN + 1]; char *ref_argv[6]; int size_refArgv = sizeof(ref_argv)/sizeof(char*);
-
Setze doch mal vor Aufruf von fcInnerClassRef einen watchpoint auf die Variable innerClass, dann stoppt der Debugger sowie sich der Inhalt dieser Variable ändert.
So hab ich schon manches Mysterium dieser Art lösen können
