【问题标题】:C++ strcpy function fails in few major casesC++ strcpy 函数在少数主要情况下失败
【发布时间】:2018-10-10 03:16:22
【问题描述】:

当这个用于交换两个字符串的代码被执行时,我得到了不想要的输出

    #include<bits/stdc++.h>
    using namespace std;

    int main()
    {
        char a2[] = "Hello world";
        char a1[] = "Geek";
        char a3[20];
        cout<<a2<<endl<<a1<<endl;

        strcpy(a3,a1);
        strcpy(a1,a2);
        strcpy(a2,a3);

        cout<<a2<<endl<<a1<<endl;
    }

我得到了这些结果:

Hello world

Geek

Geek

HelloGeek (I expect it to be HelloWorld)

我在代码中做错了什么。

【问题讨论】:

  • strcpy(a1,a2); -- 缓冲区溢出。 char 数组或任何数组不会神奇地调整自身大小。
  • 至于您在代码中做错了什么:您正在编写 C++。为什么要使用原始数组的 C 风格字符串?
  • 就像 Paul 说的:char a1[] = "Geek"; 的行实际上是在说 char a1[5] = "Geek";,而 strcpy 只复制字符 - 它不会使数组变大。
  • int a1[] = {1,2,3}; int a2[] = {4,5}; int a3[10]; -- 尝试让a2 保持 3 个整数。你不能——数组的大小是固定的,a2 现在和永远可以容纳 2 个整数。这与您现在对字符的尝试没有什么不同。

标签: c++ strcpy


【解决方案1】:

在你的程序中

char a2[] = "Hello world";

定义一个字符数组,其大小适合字符串文字"Hello world"。它可以包含 12 个字符,包括 nul 终止符。

char a1[] = "Geek";

行为相同,但"Geek" 只需要 5 个字符和 nul,因此数组长度为 5 个字符。

strcpy(a3,a1);

如你所愿,将 "Geek" 的 4 个字符复制到 a3 的 20 字节缓冲区中,然后 nul 终止。

strcpy(a1,a2);

尝试将"Hello world" 放入a1 的五个字符数组中。当缓冲区溢出时,这会调用未定义的行为。 Undefined Behavior 听起来就是这样,发生了一些未定义的事情,所以从现在开始,你不能依赖你对这个程序的任何期望。可能发生的情况是 a1 周围的其他变量之一被部分覆盖,但如果编译器生成的程序让您的计算机跳起来并开始跳马卡雷纳舞,那么编译器将同样正确。

【讨论】:

    【解决方案2】:

    详细说明 Paul Mc Kenzie 的评论:

    字符串的内存已在您的程序堆栈上静态分配。例如。包含“Geek”的数组只有空间和终止空字符,所以你不应该在那里复制更长的字符串。

    我建议您改用 std::string。它会自动处理缓冲区分配,您可以使用 = 代替 strcpy。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-17
      • 2010-11-14
      • 1970-01-01
      • 2014-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-14
      相关资源
      最近更新 更多