Problem mit stringstream->str().c_str()
-
Was willst du noch sehen?
Ist leider ein etwas größeres Projekt, sodass ich nicht alles posten kann:
aber hier noch was zu der Klasse:
class netpacket { public: netpacket(NETPACKTYPE packtype); ~netpacket(); // eine Funktion für alle Typen (int, long, float, string, ect.) wie stringstream // Durch diese Funktion unterstützt die netpacket Klasse // alle Klassen, welche auch von stringstream unterstützt werden. template <class T> netpacket& operator<<(T value) { if (finished == false) { (*stream) << value << NET_VARSEPARATOR; } else { cout << "Error: You cannot write into a finished packet. (.c_str() was called before) " << value << endl; } return *this; } const char *c_str(void); private: void finish(void); bool finished; // damit das Paket nur einmal die abschließenden Zeichen erhält std::stringstream *stream; };
netpacket::netpacket(NETPACKTYPE packtype) { finished = false; stream = new std::stringstream; (*stream) << NET_PACKSEPARATOR; (*stream) << static_cast<char>(packtype); } netpacket::~netpacket() { delete stream; } void netpacket::finish(void) { if (finished == false) { finished = true; (*stream) << NET_PACKSEPARATOR; } } const char *netpacket::c_str(void) { this->finish(); return stream->str().c_str(); }
netpacket packet(NETPACK_IDREQUEST); mastergm->getnetwork()->send(packet.c_str());
MfG
Scarabol
-
Ich bin mir unsicher, was der Standard sagt, aber m.E. müsste der
string
, der vonstr()
zurückgegeben wurde, nach Auswertung des Ausdrucks zerstört werden, was denc_str()
-Pointer noch vor Verlassen der Funktion invalidiert.Btw: gibt es einen speziellen Grund, warum stream ein Pointer ist?
-
nein eigentlich nicht...
MfG
Scarabol
-
Im übrigen solltest du das was du versendest nicht als Paket ansehen. Das ist nämlich nicht der Fall. Wenn du mit einem send-Aufruf 100 Bytes versendest, dann können auf der Gegenseite zunächst auch nur 20 Bytes lesbar sein und anschließend die restlichen 80 Bytes.
Das void bei deinen Funktionen ist in C++ übrigens nicht notwendig:
int func() reicht, du brauchst nicht int func(void) schreiben.
-
....... schrieb:
Im übrigen solltest du das was du versendest nicht als Paket ansehen. Das ist nämlich nicht der Fall. Wenn du mit einem send-Aufruf 100 Bytes versendest, dann können auf der Gegenseite zunächst auch nur 20 Bytes lesbar sein und anschließend die restlichen 80 Bytes.
Das void bei deinen Funktionen ist in C++ übrigens nicht notwendig:
int func() reicht, du brauchst nicht int func(void) schreiben.Noch eine Ergänzung: Wenn du 1000 Bytes sendest, dann könnten im ersten Sendevorgang auch nur 800 Bytes gesendet worden sein. Du kannst also nicht davon ausgehen, dass send immer sofort alles senden kann. Du musst den Rückgabewert prüfen und die fehlenden Bytes ggf. mit einem erneuten Aufruf senden:
send(socket, *(buf + sent), size, 0)
-
Oh, danke.
Bei receive hatte ich das berücksichtigt, aber an send hatte ich noch gar nicht gedacht...
MfG
Scarabol
-
ipsec schrieb:
Ich bin mir unsicher, was der Standard sagt, aber m.E. müsste der
string
, der vonstr()
zurückgegeben wurde, nach Auswertung des Ausdrucks zerstört werden, was denc_str()
-Pointer noch vor Verlassen der Funktion invalidiert.Btw: gibt es einen speziellen Grund, warum stream ein Pointer ist?
Ich bin mir zwar ebenfalls nicht sicher, aber nach meiner
Intuition schliesse ich mich dieser Einschätzung an.str() erzeugt einen String
c_str() zeigt auf das char array darinDa string nur ein temporäres Objekt ist, zeigt dein Zeiger ins Nirvana
nach dieser Zeile:static const char *result = stream->str().c_str();
-
Ich glaube euch ja, aber wie löse ich das Problem jetzt?
Würde es helfen wenn stream kein Pointer mehr ist?
MfG
Scarabol
-
Scarabol schrieb:
Ich glaube euch ja, aber wie löse ich das Problem jetzt?
Würde es helfen wenn stream kein Pointer mehr ist?
MfG
ScarabolIndem du den std::string (kein std::string& !!!) zurückgibst...
-
Scarabol schrieb:
static const char *result = stream->str().c_str(); cout << stream->str().c_str() << endl; // hier wird das richtige Ergebnis in cout geschrieben cout << result << endl; // hier wird nur endl geschrieben
Das Problem wurde bereits korrekt erklärt. Die letzte Zeile ruft undefiniertes Verhalten hervor, weil der Zeiger ungültig ist. str() gibt ein temporäres String-Objekt zurück, welches nicht lange genug lebt. Wenn Du c_str aufrufst, musst Du dir immer im Klaren darüber sein, dass der Zeiger nur solange gültig ist, bis der String verändert oder zerstört wird. In der zweiten Zeile findet die Ausgabe vor dem Zerstören des temporären Objekts statt.
-
Scarabol schrieb:
Würde es helfen wenn stream kein Pointer mehr ist?
Nein. Das hat damit nichts zu tun. Streng Dich mal an. :p