为什么这个memcpy不起作用?

时间:2016-01-21 17:01:39

标签: c++ memcpy

所以我有以下代码,是我想要做的简化版本。我有一个带有成员变量的类,我希望将其设置为潜在的各种不同的数据类型,具体取决于具体情况(我只是为此测试制作了一个随机结构)。我不断在memcpy函数上遇到seg错误,我不明白为什么。

 #include <cstdlib>
 #include <iostream>
 #include <assert.h>
 #include <string>
 #include <string.h>
 #include <stdio.h>
 using namespace std;

struct product
{
        int price;
        string name;
};


class object
{
public:
        void setData(void *ptr);
        void* data;
};


void object::setData(void *ptr)
{
        assert(ptr);
        memcpy(data, ptr, sizeof(ptr));
}


int main()
{
        product* bag;
        product ba;
        bag = &ba;
        bag->price = 5;
        bag->name = "bag";

        object test;
        test.setData(bag);

        cout<<test.data->name<<endl;

        return 0;
}

3 个答案:

答案 0 :(得分:5)

您的代码有多个问题,但SIGSEGV的直接原因是以下行: memcpy(data, ptr, sizeof(ptr));尝试将多个字节复制到未分配的指针data

另一方面,看起来您正试图使用​​完全不合理的方法在C ++中实现多态性。

答案 1 :(得分:2)

其他人提到由于使用memcpy作为要复制的字节数,sizeof(void*)不正确。但是,将sizeof更改为适当的值只会让您使用memcpy进入下一个障碍。执行此行后,您可能会遇到它:

cout<<test.data->name<<endl

原因是data->name很可能已损坏,无效,或者如果您确实看到打印的名称,则字符串处于不稳定状态。

基本上,如果结构不是 POD 类型,使用memcpy将结构设置为某个值是不可行的。

What is a POD type?

POD updates for C++ 11

您的product类的成员属于非POD类型,即std::string。您不能简单地使用来自另一个std::string对象的数据字节覆盖std::string对象(这是memcpy将要执行的操作)。

对于诸如memset或任何C导向函数之类的函数,可以说同样的事情,它设置用值指向的字节的字节。它们不能用于非POD类型。

与POD类型不同,只需执行这样的字节副本就会破坏目标对象。如果该对象包含,比如一个v-table,那么你真的会将目标对象翻录为碎片。

对于非POD类型,请使用适当的C ++技术,包括使用赋值(data = ptr)。

答案 2 :(得分:0)

另外我想这可能是问题

 cout<<test.data->name<<endl;

案例数据是无效指针,因此您需要在此处投射

 cout<<static_cast<product *>(test.data)->name<<endl;