主题:[原创]C语言中strcpy( )函数的缺点
[url=http://www.rupeng.com/forum/thread-2972-1-1-uid3391.html]【手把手教你用C语言开发Windows程序】:俄罗斯广场、贪吃蛇、学生管理系统[/url]
在C语言中,对于两个字符串复制我们一般调用<string.h>中的strcpy()函数。但是strcpy()也有其自身的缺点。
请看如下代码:
#include <stdio.h>
#include <string.h>
int main(void)
{
char str1[] = "abcd";
char str2[1];
printf("address:str1 = %p\n", str1);
printf("address:str2 = %p\n", str2);
strcpy(str2, "QD");
puts(str2);
puts(str1);
return(0);
}
在我的电脑上输出结果为:
address:str1 = 0022FF60 /*这个输出结果是由系统分配内存,每台电脑得到的结果可能不一样*/
address:str2 = 0022FF5F /*这个输出结果是由系统分配内存,每台电脑得到的结果可能不一样*/
str2 = QD;
str1 = D;
大家请看输出结果:
address:str1 = 0022FF60
address:str2 = 0022FF5F
系统先给str1分配内存起始位置在0022FF60,之后分配str2的内存位置,由于str2[1]指明只占一个字节,所以内存起始位置在0022FF5F处。
然后再看输出:
str2 = QD;
str1 = D;
为什么str2[1]表明了只占一个字节,现在用printf("str2 = %s\n", str2);却输出str2 = QD呢?这就是strcpy()函数自身的一些缺点。
原因在于,
strcpy()函数的原型为:char *strcpy(char *str1, const char *str2);
strcpy(str2, str1)函数调用中,strcpy()无法检查,str1指向的字符串的大小是否适合str2指向的数组。
如果str2指向的字符串长度为n,如果str1中有不超过n-1个字符,那么复制操作可以顺利完成。但是如果str1指向了一个更长的字符串,操作结果就得另当别论了。strcpy(str2, str1)会一直复制到str1的第一个字符'\0'为止,所以它会越过str2的数组边界继续复制。无论后面内存中的是什么,都将被覆盖。
请看本例中,由于str2[1]表明str2串只容纳一个字字,而strcpy(str2, "QD");调用中,"QD"占3个字节(算上字符串结束标志'\0'),strcpy(str2, "QD");会把字符串"QD"的第一个字符'Q'复制到内存0022FF5F中,把字符串"QD"的第二个字符'D'复制到内存0022FF60中,而0022FF60是str1数组的起始位置,导致了str1[0] = 'D',接着再把字符串"QD"的第三个字符(即字符串结束标志'\0')复制到内存0022FF61中。至此strcpy(str2, "QD");操作完成,当也意味着str1[1] = '\0'。
所以最后输出为:
str2 = QD;
str1 = D;
调用strcpy(str2, "QD");破坏了str1数组中的数据"abcd"。这就是strcpy()函数的一点缺点。
如果想用更安全的复制字符串的函数,请用strncpy()函数。
请大家多多批评、指正。
[url=http://www.rupeng.com/forum/thread-2972-1-1-uid3391.html]【手把手教你用C语言开发Windows程序】:俄罗斯广场、贪吃蛇、学生管理系统[/url]

您所在位置:


