Type conversion, und Speicherprobleme

Hi C++ ler,

ich habe ein Problem. Wenn ich diesen Code ausführe, vermute ich wird beim konvertieren des StrY Objektes in einen string, das StrY Objekt gelöscht. Damit verweist der string str auf nichts.
Das ist ein Problem.
Ich dachte, wenn ich
str = StrY(localname)
verwende würde der Konstruktor von str aufgerufen und ihm wird localname zugewiesen.
Kann mir jemand sagen, wie ich das hinbekomme? (Wenn möglich auch die Speicherlücke in meinem Hirn mit KnowHow füllen!)

Bin schon völlig verzweifelt.
Danke schon mal

Karsten

PS: Diese Klasse StrY ist zur Hilfe, da XMLString::Transcode einen pointer auf einen dynamisch allocierten Speicher zurück gibt. Er muß also automatisch gelöscht werden. Diese Klasse möchte ich so modifizieren, das ich den dynamischen Speicher lösche, aber den Inhalt in einen String kopieren kann.

class StrY
{
public :
 StrY(const XMLCh\* const toTranscode)
 {
 // Call the private transcoding method
 fLocalForm = XMLString::transcode(toTranscode);
 }

 ~StrY()
 {
 delete [] fLocalForm;
 }
 const char\* localForm() const
 {
 return fLocalForm;
 }
 operator std::string& ();

private :
 char\* fLocalForm;
};

StrY::operator std::string& ()
{
 return std::string(fLocalForm);
}

inline std::ostream& operator

Hallo!

Ich weiss ja nicht, ob alles mitbekommen habe, was ich mitbekommen haben sollte, aber:
Im Konstruktor von StrY setzt du nur einen Pointer auf einen String! Ich würde hingegen einen Speicher reservieren und in diesen Speicher hineinkopieren! Im Destruktor löscht du den Speicher dann wieder. Momentan sieht es ja so aus, dass du den Speicher der Übergabevariable freigibst! Ob das so gut ist?

Natürlich wird das Objekt bei StrY(localname); dieses Objekt in der nächsten Zeile wieder zerstört!

StrY(const XMLCh* const toTranscode)
{
fLocalForm = (char*) malloc(strlen(XMLString::transcode(toTranscode)));

memcpy (fLocalForm, XMLString::transcode(toTranscode), strlen(XMLString::transcode(toTranscode)));
}

Ich weiss aber nicht, worum es bei deinem Source geht, mit XMLString und so?!

Ich hoffe ich konnte trotz Unwissenheit helfen,
KoRn!

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi,

Im Konstruktor von StrY setzt du nur einen Pointer auf einen
String! Ich würde hingegen einen Speicher reservieren und in
diesen Speicher hineinkopieren! Im Destruktor löscht du den
Speicher dann wieder. Momentan sieht es ja so aus, dass du den
Speicher der Übergabevariable freigibst! Ob das so gut ist?

Die Methode XMLString.transcode(.) liefert einen dynamisch allocierten Speicher zurück. Ich muß ihn also nicht selbst anlegen !!

Natürlich wird das Objekt bei StrY(localname); dieses Objekt
in der nächsten Zeile wieder zerstört!

Ich hoffe ich konnte trotz Unwissenheit helfen,
KoRn!

Danke für den Versuch.

Karsten

Wo liegt denn eigentlich das Problem?

Schönen Gruß,
KoRn!

Wo liegt denn eigentlich das Problem?

Also ich erklährs mal ohne code.
Ich benutze in meinem zu erstellenden Programm einen XML Parser von Apache. Dieser XML Parser hat eine Klasse XMLString die eine statische Methode XMLString:transcode(…) besitzt.

XMLString

Diese Methode setzt die vom Parser gelieferten Unicode Zeichen in das Platformabhängige Format (ASCII) um.
Das besondere an dieser Methode ist, sie gibt einen dynamisch erzeugten Bharacter-Buffer zurück.

NOTE: The returned buffer is dynamically allocated and is the responsibility of the caller to delete it when not longer needed.

Ich möchte nun diese Funktion, damit ich mich nicht ständig um delete und stringkonvertierung herumschlagen muß dieses Ding in eine eigene Klasse kapseln. Diese Klasse soll das transcode durchführen, sich in einen String wandeln lassen, und im Destruktor den dynamischen Speicher löschen.

class StrX
{
 private:
 char\* fLocal;
 public:
 StrX(const XMLCh \*const toTranscode)
 { 
 fLocal = XMLString.transcode(toTranscode);
 }
 ~StrX(){ delete [] fLocal};

 operator string&()
 {
 return string(fLocal);
 }
}

Irgendwie funktioniert das nicht.

Schon mal Danke für die rege Nachfrage.
Karsten

Hi Karsten :smile:

class StrX
{
 private:
 char\* fLocal;
 public:
 StrX(const XMLCh \*const toTranscode)
 {
 fLocal = XMLString.transcode(toTranscode);
 }
 ~StrX(){ delete [] fLocal};

 operator string&()
 {
 return string(fLocal);
 }
}

Irgendwie funktioniert das nicht.

Der Constructor und Destructor sind in Ordnung. Jedoch versuchst du in deinem Typumwandlungs-Operator eine Referenz auf ein temporäres Objekt zurückzugeben! Nimm das „&“ da weg und die Sache wird zumindes semantisch richtig :smile:

Viele Grüße

Stefan.

Vielleicht hab ichs jetzt
Ich weiß zwar noch immer nicht, wass konkret nicht funtioniert, aber: Weisst du sicher, dass das string-Objekt str den Speicher des temporär erzeugten Objektes vom Aufruf „StrY(localname);“ kopiert oder nur wieder einen Zeiger darauf verweißt?

string str = StrY(localname);

Wenn’s dass auch nicht ist, geb’ ichs auf!

KoRn!

Halli hallo,

ich kann euch anscheinend mein Problem nicht näher bringen. Ich verstehe es selber nicht.
Also hier einiges zu meinem Problem.

Ich verwende die API von Xerces-C des Apache Project. Unter anderem auch die
statische Methode transcode der Klasse XMLString.

Hier die Dokumentation dazu:
http://xml.apache.org/xerces-c/apiDocs/class_XMLStri…

char \* XMLString::transcode ( const XMLCh \*const toTranscode ) [static] 

 Transcodes a string to native code-page. 

NOTE: The returned buffer is dynamically allocated and is the 
 responsibility of the caller to delete it when not longer needed.

Parameters: 
toTranscode The string to be transcoded 

Returns: 
Returns the transcoded string 

Wenn ich das richtig interpretiere, muss ich nach der Anwendung dieser Methode selber
für das Löschen des Speichers sorgen.
Das habe ich versucht durch die in den letzten Postings abgedruckte Klasse zu realisieren.
Das klappte jedoch nicht, da immer wenn der Speicher gelöscht werden soll ein Fehler auftritt.

Nun habe ich bei meinen Recherchen die folgende Zeile in einem Beispiel gefunden.
Hier wird jedoch kein Speicher gelöscht.

http://xml.apache.org/xerces-c/program.html

parser-\>setFeature(XMLString::transcode("http://xml.org/sax/features/validation", true) // optional

Hab ich irgendwas nicht verstanden?

Bitte um Hilfe.
Gruß Karsten