调用strcpy的结果与预期不同

时间:2014-12-18 12:32:56

标签: c strcpy

#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 编译时?

3 个答案:

答案 0 :(得分:12)

strcpy(src, &src[1]);是未定义的行为:

  

C11§7.24.2.3strcpy函数

     

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条)。