由于我在Java中习惯大量使用String类,所以转到C++下,自然也想使用STL的string。写了一个startWith函数,并在程序中多次使用。


bool startWith(string longString, string shortString) {     returnlongString.find(shortString) == 0; }

程序单元测试无误,但在集成测试时,遇到了不确定出现的缺陷。全局静态的list中的内容似乎被访问越界给改写了,然后我们集中寻找哪里出现访问越界。但在后来的反复测试中发现,甚至在简单的string赋值时,都会出现内存分配错误。于是我们开始怀疑string。在网上一查,发现 ​​有贴子讨论过C++的string是线程不安全的​​。这样测试中的种种现象就可以解释了。于是写了个多线程测试来压startWith,果然重现问题。然后重写了startWith函数。在参数中使用string类型,都会因为传递时需要拷贝而变得线程不安全。


bool startWith(const char *  longString, constchar *  shortString) {     assert(strlen(longString) < 1000);     assert(strlen(shortString) < 1000);     char ls[1000];     char ss[1000];     strcpy(ls,  longString);     strcpy(ss,  shortString);     char * cp1 = ls;     char * cp2 = ss;

    while(*cp2 !='\0')     {         if (*cp1 == *cp2)         {             cp1++;             cp2++;         } else {             returnfalse;         }     }     return true; }

总结:

  • string装得像个栈变量,但却操作堆空间,而且线程不安全
  • 线程是否安全应该属于使用契约,如何通过防御式设计来避免?
  • 集成测试应该尽早进行
  • 不确定出现的缺陷大多与多线程有关
  • 不了解原理的复用,可能降低软件开发的效率和品质
  • 从一个侧面理解了​​为什么Linus要炮轰C++​
  • 这段c代码不好看,怎样写得好看些?