直接改写std::string内存导致的问题
今天帮一个同事查问题: 他写了一个全局的string变量, 在程序运行过程中可能会对该变量进行解析操作, 但是在持续运行过程中第二次访问到这个全局变量的时候, string的内容发生了改变. 他代码大体逻辑类似下面这样:
|
|
按照代码的意图, 从main传入的str应该是不会因为process处理发生变化的, 因为process处理的时候从原数据复制了一份newstr进行处理. 在gcc 4.1.2下编译, 输出结果如下:
|
|
通过运行结果我们可以看到process完后, str的内容的确发生了变化, 根据我们输出的string地址, 发现复制前后的字符串数据指针的地址是相同的. 正是由于string提供的这种copy-on-write机制, 导致strtok处理数据时修改了原始数据内容.
虽然看起来这个问题是 string的实现中提供了cow的特性导致的, 但是根本原因是没有按照函数的参数规范进行编码, 强制将const char转为char进行操作, 导致原始数据内容被改写. 对于我们调用的接口(尤其标准库的接口), 如果发现未带有const限定符, 应仔细考虑是否有对输入数据改写的可能, 然后在决定如何传递参数.