本节书摘来自异步社区出版社《从缺陷中学习C/C++》一书中的第6章,第6.4节,作者: 刘新浙 , 刘玲 , 王超 , 李敬娜 , ,更多章节内容可以访问云栖社区“异步社区”公众号查看。
从缺陷中学习C/C++代码示例
class MyString { public: MyString(){ s_ = (char *)malloc(strlen(str) + 1); strcpy(s_, str); } ~MyString() { printf("destory\n"); } friend MyString operator+(const MyString &lstr, const MyString &rstr){ size_t llen = strlen(lstr); size_t rlen = strlen(rstr); char buf[llen + rlen + 1]; strcpy(buf, lstr); strcat(buf, rstr); return MyString(buf); } operator const char *() const { //当string转换char* 时调用 return _s; } private: char *_s; }; int main() { MyString s1("hello "), s2("world !"); const char *p = s1 + s2; printf("%s\n", p); return 0; }现象&结果程序运行时通常是正常的,但有时会出错,特别是在多线程时,会出现奇特的错误:例如,指针p指向的内容不是期望的内容。
Bug分析错误出在main函数中的const char *p = s1 + s2代码行处。程序会首先生成一个临时对象,用来存储s1+s2的值,然后再把临时对象的值赋给p,随后该临时对象析构。所以,指针p指向了一块非法内存。因为临时对象已经被析构,所以这块非法内存被系统识别为“未使用”的状态,可以被再分配使用。如果在程序中没有其他操作读写这块内存时,其内容还没有被改变,所以,可能输出符合程序预期的正确结果。但是,没有任何方法阻止那块内容的改变。所以,如果有其他操作对这块内存单元进行写操作后,可能输出的是随机值。
正确代码在main函数中显式给出临时对象:
int main() { MyString s1("hello "), s2("world !"); String temp = t1 + t2; const char *p = temp; printf("%s\n", p); return 0; }本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。
相关资源:敏捷开发V1.0.pptx