Kekeliruan mengenai Penukaran Antara aliran rentetan, rentetan dan aksara*
Isu ini timbul apabila menukar rentetan yang diperoleh daripada stringstream.str(). c_str() ke dalam const char*. Memahami pengurusan memori dan jangka hayat rentetan yang dikembalikan adalah penting untuk mengelakkan kemungkinan ralat.
Coretan kod menunjukkan isu:
#include <string> #include <sstream> #include <iostream> int main() { stringstream ss("this is a string\n"); string str(ss.str()); const char* cstr1 = str.c_str(); const char* cstr2 = ss.str().c_str(); cout << cstr1 // Prints correctly << cstr2; // ERROR, prints out garbage system("PAUSE"); return 0; }
Andaian bahawa stringstream.str().c_str( ) boleh diberikan kepada const char* adalah tidak betul. Ini membawa kepada pepijat di mana cstr2 mencetak sampah.
Memahami Pengurusan Memori
stringstream.str() mengembalikan objek rentetan sementara yang sah hanya sehingga akhir daripada ungkapan semasa. Apabila ungkapan selesai, objek sementara dimusnahkan dan penunjuk kepada datanya (dikembalikan oleh c_str()) menjadi tidak sah.
Menyelesaikan Ralat
Untuk menyelesaikan isu ini, objek rentetan sementara mesti disimpan dalam pembolehubah yang berasingan, seperti:
const std::string tmp = stringstream.str(); const char* cstr2 = tmp.c_str();
Dengan menyimpan objek sementara dalam tmp, jangka hayat penuding dilanjutkan dan mencetak cstr2 kini berfungsi dengan betul.
Penjelasan Mata Bonus
Dalam blok kod yang diubah suai:
cout << cstr // Prints correctly << ss.str().c_str() // Prints correctly << cstr2; // Prints correctly (???)
Semua penyata cetakan kini berfungsi dengan betul kerana:
Atas ialah kandungan terperinci Mengapakah `stringstream.str().c_str()` Menyebabkan Ralat Memori dalam C ?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!