参考:http://lwn.net/Articles/414467/
这里提到了 memcpy 的一个“准bug”。虽然CT6.3下 glib 对memcpy 函数做了优化,但同时也带来了一个bug:src 和 dst 不能有overlap!
如果有overlap,后果不可预知!
使用memcpy 函数时要谨慎,如果src 和 dst 没有overlap,可以不用管这里的文字;如果有overlap,就设法绕过去。
一个简单的workaround如下:即用红色的代替蓝色的
也可以用Safe C的 memcpy_s 函数替换掉memcpy 函数
注意:
1. 这里提到的bug,并不是必现的,请不要抱着侥幸的心理去做带有overlap的操作!
CentOS 4.4之所以没有这个问题,而CentOS6.3有,是因为系统升级的时候把安全性提高了,带来的一个负面影响就是,先前被“包庇”的memcpy的bug浮出了水面!
Linus Torvads都不承认它是个bug,而只是个issue(但man手册里确实提到了"The memory areas should not overlap"),那咱们自己就得小心使用。
2. 用man memcpy去查手册,结果发现:
CT4.4:
The memcpy() function does not check for the overflow of the receiving memory area. (没有提到overlap的问题)
CT6.3:
The memory areas should not overlap. Use memmove(3) if the memory areas do overlap. (即在overlap情况下,可以用memmove来代替memcpy)
3. 对于下面的代码,貌似不能重现那个bug,但不管怎样,在正式的代码中不要让src和dst出现重叠!
#include <string.h> #include <iostream> using namespace std; int main() { char str[10] = "123456789"; cout << sizeof(str) << endl; for(int i = 0; i < sizeof(str); ++i) { cout << str[i] << " "; } cout << endl; int pos = 2; //memcpy(str + pos, str + pos + 1, sizeof(str) - pos -1); memcpy(&str[pos], &str[pos + 1], sizeof(str) - pos -1); for(int i = 0; i < sizeof(str); ++i) { cout << str[i] << " "; } cout << endl; return 0; }