参考: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;
}