Assalamualaikum, pembaca-pembaca sekelian.
Hari ini saya akan membincangkan tentang satu isu yang telah agak lapuk di dunia ini iaitu
Ya benar tuan-tuan, Belia (sebenarnya saya) Benci C++.
Mari kita mulakan dengan status update saya pada hari ini, dan sebenarnya dari semalam lagi saya stuck kat benda ini. So harini saya telah menyambung project C++ saya yang ke…. saya tak ingat. Dalam pembikinan projek itu, yang sebenarnya agak besar sehinggakan saya terpaksa men-test dahulu bahagian kecil sebelum menyambung implimentasi yang seterusnya. Dalam pada itu, ini merupakan code test tersebut.
void test_gdserialization(){
std::cout<<"\nDebugging DoubleArray Serialization";
DoubleArray* thearr=new DoubleArray(10);
for(int i=0;i<10;i++){
thearr->data()[i]=(double)(rand()%100)/(double)(rand()%100);
}
std::cout<<"\nSerializing, data:";
QString save=thearr->toString();
std::cout<<"\n"< std::cout<<"\nEnd Save";std::cout<<"\nRetry Print";std::cout<<"\n"< std::cout<<"\nBegin load";DoubleArray* newarr=new DoubleArray(1092);newarr->fromString(save);std::cout<<"\nEnd load,Serializing,data:";QString newdata=newarr->toString();std::cout<<"\n"< if(newdata==save){std::cout<<"\nString match";}else{std::cout<<"\nString does not match";}
}Long story, make short. Basically, apa yang code ini cuba buat ialah ia akan serialize DoubleArray yang pertama menggunakan 'toString()'. Dan ambil resultnya sebagai QString. QString sebahagian daripada Qt framework. Kenapa pakai QString? Kerana implicit sharing yang sangat memudahkan kerja. So dah dapat string daripada DoubleArray tu, kita buat satu lagi DoubleArray dan kemudian deserialize string yang tadi tu. Tapi disebabkan pelbagai masalah yang bermacam-macam dan setalah mengubah-ubah pelbagai code, akhirnya code fromString() menjadi sebegini:
void DoubleArray::fromString(QString data){std::cout<<"\nIn Double Array fromString()\nThe data is\n";std::cout< std::cout<<"Is it ok?";std::string buffer(data.toStdString());std::istringstream inputstream(buffer);boost::archive::xml_iarchive inputarchive(inputstream);DoubleArray* thenewone=this;inputarchive>>BOOST_SERIALIZATION_NVP(thenewone);
}Ok, so basically ianya benda biasa. Lupakan perkara yang berserabut pada lima baris yang terakhir. Fokus kepada baris yang kedua. Apa yang ia buat ialah, ia print balik apa yang diberi di method argument yang pertama iaitu 'data' iaitu hasil daripada serialization yang lepas. Kalau kita tengok balik code sebelum ini di 'test_gdeserialization' baris yang ke 9 dan ke 12, ianya adalah arahan yang sama dan disebabkan 'fromString' yang di-call pada baris yang ke 15 menggunakan QString 'save', ia patut bertindak dengan cara yang sama betul? Tapi apa yang terjadi apabila kita jalankan test tersebut:
Haaa!? Ape kes!? Kok jadi begini-deh! Sabar-sabar, kita gali sikit ape yang jadi...
Teng, teng, teng..... 'memory corruption'.
So apakah yang telah terjadi? Kalau kita cuba google perkara ini, kita akan mendapati yang 'malloc(): memory corruption(fast)' menandakan bahawa program tersebut telah cuba untuk mengakses data di luar range yang telah diminta daripada 'malloc()'. Tetapi ada beberapa kemushkilan, di sini. Iaitu, di function 'test_gdeserialization' baris yang ke 9 dan ke 12, telah mem-print seperti mana juga di 'fromString()'. Hal ini dapat dibuktikan apabila kita menggali lagi dalam error tadi:
Ada perkataan 'end save' dan 'retry print' iaitu std::cout di 'test_gdeserialization' pada baris yang ke 10 dan ke 11, itu menandakan bahawa 'std::cout' pada baris yang ke 9 telah berjaya di laksanakan. Begitu juga dengan 'std::cout' pada baris yang ke 12, dibuktikan dengan mesej:
Perkataan 'Begin Load' patut dikeluarkan pada baris yang ke 13, yang bermakna 'std::cout' pada baris yang ke 12 telah berfungsi.
So... Ape ke hehnye? And then entah kenapa, apabila kite try sekali lagi dalam debug mode, masalahni tak keluar, keluar masalah lain (biasa lah tu). Tapi yang kat release mode masih sama. So far lah.