2007年3月12日星期一

关于函数strcat()

摘自glibc-2.4/string/strcat.c:
char *
strcat (dest, src)
char *dest;
const char *src;
{
char *s1 = dest;
const char *s2 = src;
reg_char c;

/* Find the end of the string. */
do
c = *s1++;
while (c != '\0');

/* Make S1 point before the next character, so we can increment
it while memory is read (wins on pipelined cpus). */
s1 -= 2;

do
{
c = *s2++;
*++s1 = c;
}
while (c != '\0');

return dest;
}
摘自MVC:
char * strcat (char * dst, char * src)
{
char * cp = dst;

while( *cp )
++cp; /* Find end of dst */
while( *cp++ = *src++ )
; /* Copy src to end of dst */
return( dst );
}
从函数strcat()的实现中我们可以看出,它并不会对其参数进行检查。因此我们写程序时应该格外小心,因为源字符串若长度不够,则会溢出,从而有可能覆盖掉邻接的内存里的内容。可以看一个例子:
int main()
{
char a[] = {'1','1','1','\0'};
char d[] = {'2','2','2','\0'};
char s[] = {'3','3','3','\0'};

printf("before strcat() a is %s\n", a);
printf("before strcat() d is %s\n", d);

strcat(d,s);

printf("after strcat() a is %s\n", a);
printf("after strcat() d is %s\n", d);
}
其输出为:
root@BlueIris:~# ./strcpy_error
before strcat() a is 111
before strcat() d is 222
after strcat() a is 33
after strcat() d is 222333
可见字符数组a已经被d溢出的部分所覆盖。原理见下图。

没有评论: