与同事互相code review的时候,同事指出我的代码在使用strcpy,建议改为strncpy,避免缓冲区溢出问题。于是不加思索改为strncpy,谁知道不小心遇到strncpy另一个问题,也可能导致缓冲区溢出。
先贴上strncpy的函数原型:
char *strncpy(char *dest, const char *src, size_t n)和strcpy相比多了一个参数n,意思是最多拷贝n个字节,以避免缓冲区的溢出。
我的代码是这样的:
char dest[8] = {0};char *src = "12345678";strncpy(dest, src, sizeof(dest));如果不仔细看strncpy 的手册的话,看起来是没什么问题。但这其实是有问题的,strncpy 的最后一个参数n, 当n小于或等于src的长度时,会拷贝n个字节到dest,这n个字符不包含' '。也就是说上面的拷贝完成后dest数组内部是这样的:{'1','2','3','4','5','6','7','8'},即没有以' '结尾。
如果使用printf打印dest数组的话,结果是未知的,因为printf打印字符串直到遇到' '才会终止,所以除了打印dest的内容,还会打印dest数组相邻的内存的值,这是很危险的。
正确的用法是:
strncpy(dest, src, sizeof(dest)-1);从而避免导致缓冲区溢出。