回 帖 发 新 帖 刷新版面

主题:[原创]C语言中strcpy( )函数的缺点

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]

回复列表 (共9个回复)

沙发

微软提供了更安全的strcpy_s

板凳

经典的安全问题啦 现在新版的LINUX都有保护了

3 楼

当你写strcpy时,就有一个契约:目的区要能容纳得下原串。

照你这逻辑,没有任何东西是安全的。
strncpy并不是安全的,比如
char str1[] = "abcd";
char str2[1];
strncpy( str2, 100, str1 );

甚至int都不是安全的
int a = 0x7FFFFFFFFFFFFFFF;
printf( "%#x", a ); 输出为 0xffffffff

4 楼

C语言有好些函数都是不安全的。

5 楼

对编程有兴趣的加群73208436

6 楼

这正是C语言的魅力啊,可以做到其它相对“安全”的语言所不能做的事,比如...

7 楼

这个算什么缺点哦。明显要有足够空间才去strcpy()嘛。这个必须保证了嘛。。
     不然调用它干嘛。

8 楼

这个就跟数组不能越界访问一样。

9 楼


[em1]这个应该不算strcpy的缺陷,这个问题的出现就是因为你违反了C标准中制定的规则;编程中有很多是必须遵守的规则,比如int,float的大小问题,如果超出了就会显示异常....

我来回复

您尚未登录,请登录后再回复。点此登录或注册