微软 strcat()函数实现的疑问、、、

TandyT 2011-09-13 08:40:07
我用的是VS2005 ,在安装目录看到的源码文件夹里的 strcat.c 文件,有字符串拼接函数 strcat()的实现,如下:

char * __cdecl strcat (
char * dst,
const char * src
)
{
char * cp = dst;

while( *cp )
cp++; /* find end of dst */

while( *cp++ = *src++ ) ; /* Copy src to end of dst */

return( dst ); /* return dst */

}



微软是如何保证,在函数里调用这个strcat() 来拼接字符串时,不越界访问的?因为在这个实现函数里,只是单纯的用一个指针遍历 dst 数组,并把 src 数组的内容复制到dst里,而不用考虑 dst 数组的容量是否够大!

如果我要复制的数组,比如数组 char src[1024*600],而 char dst[]="abc"; 那调用这个函数时,dst的容量只有4字节(包括结束符),而要复制的数组大小为 1024*600 字节。即使有可能 dst 和 src 是分配在栈中的一段连续内存里的,也许可以正常复制 src数组到 dst ,但这样复制完后,src[] 数组的内容岂不是被修改了?

很不解微软是如何解决这个问题的,还是根本就不需要解决。。。。。我多虑了?囧。。。。。。
...全文
401 25 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
lcy_888 2011-09-14
  • 打赏
  • 举报
回复
现在微软的很多C下的字符串函数后面都加上了"_s",所以我们最好用加了"_s"的,加了"_s"的字符串函数在参数中基本有改变,其实这些改变大部份就是用来防止BUG的。比如strcpy与strcpy_s,楼主自己用用就知道了。
jyh_baoding 2011-09-14
  • 打赏
  • 举报
回复
很多函数是指针操作,对越界没有检测
辰岡墨竹 2011-09-14
  • 打赏
  • 举报
回复
另外注意strcat、strcpy、memcpy这些函数都如果遇到源和目标部分重叠的情况时行为是未定义的。
ringphone 2011-09-14
  • 打赏
  • 举报
回复
操作数据的合法性由调用者保证,函数不负责检查。
用户 昵称 2011-09-14
  • 打赏
  • 举报
回复
不做任何保证。
TandyT 2011-09-14
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 saiyaman5 的回复:]
引用 8 楼 shenyi0106 的回复:

while( *cp )
不是又判断么?*cp是一个ASCII值啊,\0 = 0,所以没有任何问题


lz的意思是dst的空间不足...
[/Quote]

嗯,是这意思
TandyT 2011-09-14
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 shenyi0106 的回复:]
while( *cp )
不是又判断么?*cp是一个ASCII值啊,\0 = 0,所以没有任何问题
[/Quote]
你没看明白我的意思,在这个函数里,
while( *cp )
cp++; /* 这个循环是找到 dst数组的结束符位置,这里当然没错*/

while( *cp++ = *src++ ) ; /*而这个循环,是把src数组逐个元素拷贝到dst数组里,一直到*src=='\0'为止,这样就可能有问题了,我前面说了,[color=#0000FF]如果dst数组容量很小,而src的容量很大,就会越界或者是修改src本身的数据了[/color]。 */

__________________________________
当然,也许各位朋友说的对,这个检查是要由程序员自己来检查解决。

saiyaman5 2011-09-14
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 shenyi0106 的回复:]

while( *cp )
不是又判断么?*cp是一个ASCII值啊,\0 = 0,所以没有任何问题
[/Quote]

lz的意思是dst的空间不足...
shenyi0106 2011-09-14
  • 打赏
  • 举报
回复
while( *cp )
不是又判断么?*cp是一个ASCII值啊,\0 = 0,所以没有任何问题
v_table 2011-09-14
  • 打赏
  • 举报
回复
strcat_s
TandyT 2011-09-14
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 jxcr1984 的回复:]
微软什么都给你考虑好了,还要这些有证/无证的程序员干嘛?
[/Quote]

这么说还得多谢微软为我们创造了就业机会哈
TandyT 2011-09-14
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 dfasri 的回复:]
超界是不能保证的.
但楼主说的strcat自身, 那么src岂不就自己改变了? 从代码里面可以看出来一点, 假如真的是strcat自身的话, 就会直接变成死循环. 因为src已经没有'\0'这个字符了.
[/Quote]

、、、、啥意思?谁说 src 指向的内存里没有 '\0',传进来的是一个指针,但是这个指针指向的数组的最后一个元素是 '\0' 。
xu20101010 2011-09-14
  • 打赏
  • 举报
回复
c中有很多函数都不检查越界 这也是 溢出攻击的原因所在 一个有经验的黑客 能够构程一个巧妙的字符串 然后在发生溢出是 让程序转到他想要执行的地方
今晚又失眠 2011-09-14
  • 打赏
  • 举报
回复
微软什么都给你考虑好了,还要这些有证/无证的程序员干嘛?
还没淹死的鱼 2011-09-14
  • 打赏
  • 举报
回复
如果越界,程序运行时会提示非法访问的,或者是堆栈溢出。

所以嘛,还是寄希望于程序员在调试时发现吧
dfasri 2011-09-14
  • 打赏
  • 举报
回复
超界是不能保证的.
但楼主说的strcat自身, 那么src岂不就自己改变了? 从代码里面可以看出来一点, 假如真的是strcat自身的话, 就会直接变成死循环. 因为src已经没有'\0'这个字符了.
fenshucangku 2011-09-14
  • 打赏
  • 举报
回复
没有这个保证,越界的事经常出现
nnull 2011-09-14
  • 打赏
  • 举报
回复
该函数不能保证内存越界
youngwolf 2011-09-14
  • 打赏
  • 举报
回复
这个crt怎么保证,就算是用strcpy_s也不能保存,因为调用者可以传一个错误的大小进去,我就见过。

xxx_s系列函数,在有些情况下,可以保证不出错,就是编译器能推导出目的地址的大小的情况下(它通过模板实现的,vc2010,其它版本我不保证),比如:
char buff[1024];
strcpy_s(buff, "123"); //不要strcpy_s(buff, 1024, "123");要让编译器自己去推导(虽然两种写法都能通过编译)
ccing 2011-09-13
  • 打赏
  • 举报
回复
编译的时候难道你没注意到会有一个警告吗?
加载更多回复(5)

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧