~对初学者属于深入理解吧,高手请勿在此浪费宝贵时间~
看到这样一个改错题:
char p[5];
char* s="12345";
strcpy(p,s);
cout << p << endl;
错误之处是很显然的,作为字符串字面值的"12345"会在结尾处自动加上空字符null,从而长度是6,上面的strcpy是会越界的,从而是个越界错误。
问题是我以为这样的程序编译的时候会出错呢!但是我在vc上运行时是可以输出正确结果的,这让我很是纳闷!后来找到了strcpy的源代码才知原因,strcpy函数是不进行越界处理的. 又因为strcpy连null一起复制,从而p能输出正确的结果"12345"
/**//*The strcpy function copies strSource, including the terminating null character, to the location specified by strDestination. No overflow checking is performed when strings are copied or appended. The behavior of strcpy is undefined if the source and destination strings overlap.*/
char * __cdecl strcpy(char * dst, const char * src)
{
char * cp = dst;
while( *cp++ = *src++ )
; /**//* Copy src over dst */
return( dst );
}
貌似strcpy虽然不进行越界处理,仍然是个挺好的函数呢,但是注意了,下面的代码就能暴露出strcpy 的缺点了.
char p[5];
char *s = "12345678";
strcpy(p,s);
cout << p <<endl; //输出12345678,而不是我们所设想的12345
为了不因不知s的长度而犯下错误,推荐使用strncpy。但是是不是用了strncpy就万无一失了呢?看下面的代码:
char p[5];
char* s = "12345";
strncpy(p,s,5);
cout << p <<endl; //12345*&^(后面表示乱码)
不是都限制个数了么?为什么后面又有乱码?
问题来自在上述情形strncpy是不会复制字符串s后面的null的,不是以null结束的p不会输出正确结果的。
仍然给出strncpy的源代码:
/**//*The strncpy function copies the initial count characters of strSource to strDest and returns strDest. If count is less than or equal to the length of strSource, a null character is not appended automatically to the copied string. If count is greater than the length of strSource, the destination string is padded with null characters up to length count. The behavior of strncpy is undefined if the source and destination strings overlap.*/
char * __cdecl strncpy ( char * dest, const char * source, size_t count )
{
char *start = dest;
while (count && (*dest++ = *source++)) /**//* copy string */
count--;
if (count) /**//* pad out with zeroes */
while (--count)
*dest++ = '\0';
return(start);
}
那strncpy这么不稳定,为何用它?strncpy经常用于修改一个长字符串中间的一部分(看出不复制null的原因了吧!),如果实在要用到上述的代码上,就在代码最后加上p[5] = '\0'; 吧!