【问题标题】:memcpy causing program to crash with initialized destinationmemcpy 导致程序在初始化的目的地崩溃
【发布时间】:2015-01-03 06:16:22
【问题描述】:

我正在开发一个更大的程序,而 memcpy 导致它崩溃。我在一个小程序中复制了这种情况,它做同样的事情。我注意到由于某种原因这个程序运行良好

// Runs fine
#include <iostream>

int main() {
    char* s1 = "TEST"; // src
    char* s2; // dest

    memcpy(s2, s1, strlen(s1) + 1);
    std::cout << s2 << std::endl; // Should print "TEST"

    return 0;
}

但是这个程序崩溃了

// Crashes
#include <iostream>

int main() {
    char* s1 = "TEST"; // src
    char* s2 = ""; // dest - Note the small change

    memcpy(s2, s1, strlen(s1) + 1);
    std::cout << s2 << std::endl; // Should print "TEST"

    return 0;
}

我不确定为什么会这样。有人可以解释一下为什么会崩溃吗?

谢谢!

【问题讨论】:

  • 如果使用 C++ 编码,您应该避免使用原始的 char* 指针并使用 std::string 和 C++ 智能指针。

标签: c++ crash memcpy char-pointer


【解决方案1】:

memcpy 导致错误的原因是您试图将s1 的内容复制到由字符串文字指向的内存中,这是未定义的行为,因为字符串文字不可写,甚至如果是的话,就没有足够的空间了。

您的第一个代码也是无效的,因为它使memcpy 进入由未初始化指针指向的内存 - 再次成为未定义的行为。

您可以通过添加对new 的调用来修复第一段代码,如下所示:

char* s2 = new char[strlen(s1)+1];

第二段代码可以这样固定:

char s2[5] = "";

【讨论】:

    【解决方案2】:

    两个程序都有undefined behavior。所以如果第一个没有崩溃(它取消引用一个未初始化的指针!),那只是你不走运。

    目的地(memcpy 的第一个参数)应该是一个已分配且可写的区域。本地数组(或指向堆栈上的本地数据的指针,可能在某些调用者的框架中) - 或指向全局或静态数据的指针 - :

    char arr[32];
    memcpy (arr, s1, strlen(s1)+1);
    

    或堆分配区域:

    char*ptr = malloc(32);
    if (!ptr) { perror("malloc"); exit(EXIT_FAILURE); };
    memcpy (ptr, s1, strlen(s1)+1);
    

    请注意,像 "ABC" 这样的文字字符串通常是不可可写的。它们位于只读数据段中。

    以上是C代码。如果你想要 C++ 代码,请使用 new(但在 C++ 中,你应该使用 std::string

    顺便说一句,要非常小心避免buffer overflows。上面的代码有效,因为在这种情况下strlen(s1) 小于 31。

    【讨论】:

    • 感谢您的帮助!这修复了崩溃,因此帮助我修复了另一个错误!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-17
    相关资源
    最近更新 更多