#include <stdio.h>
#include <string.h>
int main()
{
char src[]="123456";
strcpy(src, &src[1]);
printf("Final copied string : %s\n", src);
}
当我使用 Visual Studio 6编译器时,它会给我预期的答案&#34; 23456
&#34;。
该程序如何打印&#34; 23556
&#34;用 gcc 4.7.2 编译时?
答案 0 :(得分:12)
strcpy(src, &src[1]);
是未定义的行为:
C11§7.24.2.3
strcpy
函数
strcpy
函数复制s2
指向的字符串(包括终止空值) 字符)到s1
指向的数组中。 如果在对象之间进行复制 重叠,行为未定义。
顺便说一句,memcpy
类似(但不是memmove
)。请参阅C FAQ: What's the difference between memcpy
and memmove
。
答案 1 :(得分:2)
这是未定义的行为。请改用memmove
功能。 memmove
旨在允许源缓冲区和目标缓冲区重叠。
memmove(src, &src[1], strlen(&src[1]) + 1) ; // + 1 for copying the terminating zero
答案 2 :(得分:2)
来自ISO / IEC 9899:TC3(c99)
7.21.2.3 strcpy函数
概要
1
#include <string.h>
char *strncpy(char * restrict s1,
const char * restrict s2,
size_t n);
描述
2 strcpy函数复制s2指向的字符串(包括终止空值) 字符)进入s1指向的数组。 如果在对象之间进行复制 重叠,行为未定义。
所以你所做的只是未定义的行为;)
您还可以看到ANNEX J.2
说明未定义行为的情况,并注明如何预防:
在以下情况下,行为未定义:
[...]
- 尝试使用库将对象复制到重叠对象 除了明确允许的功能(例如,memmove)(第7条)。