【问题标题】:Why my source is changing when using strcpy in c为什么在 c 中使用 strcpy 时我的源代码发生了变化
【发布时间】:2011-07-17 10:06:34
【问题描述】:

使用 strcpy 后,源被损坏并获得正确的目的地。以下是我的代码,请告诉我为什么我的源代码被破坏了?如果我对第二个字符数组 q[] 保持固定大小,那么我的源不会被更改。为什么会出现这种奇怪的行为。 -
我正在使用 MSVC 2005

void function(char* str1,char* str2);
void main()
{

    char p[]="Hello world";
    char q[]="";
    function(p,q);
    cout<<"after function calling..."<<endl;
    cout<<"string1:"<<"\t"<<p<<endl;
    cout<<"string2:"<<"\t"<<q<<endl;
    cin.get();
}

void function(char* str1, char* str2)
{
    strcpy(str2,str1);
}

输出:

after function calling...
string1:        ld
string2:        Hello world

提前致谢,
马拉地语

【问题讨论】:

  • “在使用 strcpy 源被损坏并获得正确的目的地后”,这是没有意义的。
  • @Daniel,是的,这是有道理的,因为 q 上的 strcpy 会覆盖为 p 分配的内存。
  • 它已损坏并获得正确的目的地。很抱歉,但我不明白这句话背后的含义。当我看到 strcpy(...) 和 char q[] = "".
  • 如果使用 C++,使用 std::string 可能是合理的。运算符 = 完全符合您的需要。
  • @Daniel:它是源 string,而不是源 code。这让我有点困惑。

标签: c++ c strcpy


【解决方案1】:

strcpy 不分配存储字符串所需的内存。 在执行strcpy 之前,您必须在str2 中分配足够的内存。 否则,当您覆盖一些未分配的内存时,您会得到未定义的行为。

【讨论】:

    【解决方案2】:

    q 仅包含 1 个字符的空格,即终止 \0。 请阅读一本关于 C 的书——你需要学习一些关于内存管理的知识。

    你的记忆很可能是这样的(简化的):Qpppppppppppp。所以当你strcpy到q时,你会覆盖p的部分内存。

    由于您使用的是 C++:只需使用 std::string 和或 std::stringstream 而不是原始 char 数组。

    【讨论】:

      【解决方案3】:

      在您的代码中,q 是一个单元素数组(基于 "" 的长度,由于空终止符而等于 1),因此它不能包含整个字符串。因此,您不能执行strcpy,因为它会覆盖无效的内存位置(尝试将太多数据写入数组)。

      声明q 足够大以包含您的字符串。另外,为了安全起见,您可以使用strncpy

      【讨论】:

      • 可悲的是strncpy 不是“安全”strcpy,而是用于固定大小的字符串,因此如果字符串与缓冲区一样长,它不会以 NUL 终止它。非标准安全替代方案是strlcpy
      【解决方案4】:

      char q[] = ""; 创建一个只有 1 个元素的字符数组 - 将更多数据复制到其中不会为其保留更多内存。

      所以,当你写超过为 q 保留的空间时,你会开始覆盖 p 中的内容 - 这两个变量在内存中彼此相邻。

      【讨论】:

        【解决方案5】:

        每个人都说对了一半。代码失败,因为没有为副本保留空间,正如其他人正确指出的那样。缺少的部分是您的对象在堆栈上,而不是堆上。因此,由于堆栈无法再展开,您的代码不仅可能而且不可避免地会损坏。

        【讨论】:

        • 抱歉,Ernest,没有看到您的评论。
        【解决方案6】:

        数组“q”只有一个字节长;它绝对没有空间容纳字符串“Hello, World”!当您尝试将“Hello, World”复制到 q 时,您最终会超出 q 的边界并覆盖堆栈上与其相邻的 p。我想画出这些东西在堆栈上的布局图,你可以确切地确定为什么最终出现在 p 中的垃圾只是“ld”。

        【讨论】:

          【解决方案7】:

          strcpy 希望您提供一个分配的存储缓冲区,而不仅仅是一个 char* 指针。如果您将char q[]=""; 更改为char q[50];,它将起作用。由于您只给 strcpy 一个指向零长度字符串的指针,因此它没有足够的空间来存储复制的字符串并覆盖也就是破坏内存。

          【讨论】:

            猜你喜欢
            • 2016-01-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-12-02
            • 1970-01-01
            • 1970-01-01
            • 2011-12-20
            相关资源
            最近更新 更多