[英]Why doesn't this memcpy work?
So I have the following code, a simplified version of what I want to do.所以我有以下代码,我想做的简化版本。 I have a class with a member variable that I want to set to potentially a variety of different data types, depending on the situation (i just made a random struct for this test).我有一个 class 的成员变量,我想根据情况将其设置为可能的各种不同的数据类型(我只是为此测试创建了一个随机结构)。 I keep getting seg faults on the memcpy function though, and I have no idea why.我一直在 memcpy function 上遇到段错误,我不知道为什么。
#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;
}
Your code has multiple issues, but a direct cause of SIGSEGV is following line: memcpy(data, ptr, sizeof(ptr));
您的代码有多个问题,但是SIGSEGV的直接原因是以下行: memcpy(data, ptr, sizeof(ptr));
which tries to copy a number of bytes into unallocated pointer data
. 它试图将多个字节复制到未分配的指针data
。
On a side note, it looks like you are trying to achieve polymorphism in C++ using completely inapproriate methods. 附带说明一下,您似乎正在尝试使用完全不合适的方法在C ++中实现多态。
Others have mentioned that the memcpy
is not correct due to using sizeof(void*)
as the number of bytes to copy. 其他人提到memcpy
是不正确的,因为使用sizeof(void*)
作为要复制的字节数。 But changing the sizeof
to an appropriate value will just have you hit the next stumbling block with using memcpy
. 但是将sizeof
更改为适当的值只会使您使用memcpy
到达下一个绊脚石。 You would probably encounter it as soon as you execute this line: 执行此行后,您可能会遇到它:
cout<<test.data->name<<endl
The reason is that data->name
is more than likely corrupted, invalid, or if you did actually see a name printed, the string is in an unstable state. 原因是data->name
很可能已损坏,无效,或者如果确实看到了打印的名称,则字符串处于不稳定状态。
Basically, using memcpy
to set a struct to a certain value isn't going to work if the struct is not a POD type. 基本上,如果该结构不是POD类型,则使用memcpy
将结构设置为某个值将不起作用。
POD updates for C++ 11 C ++ 11的POD更新
Your product
class has a member that is a non-POD type, namely std::string
. 您的product
类具有一个非POD类型的成员,即std::string
。 You cannot simply overlay a std::string
object with bytes of data from another std::string
object (which is what that memcpy
will be doing). 你不能简单地叠加一个std::string
对象从另一个数据字节std::string
对象(这是什么memcpy
会做)。
The same thing can be said for functions such as memset
or any C
oriented function that sets the bytes of what is pointed to with values. 对于诸如memset
函数或任何设置值所指向的字节的面向C
的函数,都可以说相同的话。 They cannot be used on non-POD types. 它们不能用于非POD类型。
Unlike POD types, just doing a copy of bytes like that will corrupt the destination object. 与POD类型不同,仅执行类似的字节副本将损坏目标对象。 If that object contained, say a v-table, then you really would be ripping the destination object to shreds. 如果包含该对象(例如v表),那么您实际上将把目标对象撕成碎片。
For non-POD types, use the proper C++ techniques, which include using assignment ( data = ptr
). 对于非POD类型,请使用适当的C ++技术,其中包括使用赋值( data = ptr
)。
Also I suppose it could be problem here 我也想这可能是个问题
cout<<test.data->name<<endl;
case data is void pointer so you need cast here 案例数据为空指针,因此您需要在此处进行投射
cout<<static_cast<product *>(test.data)->name<<endl;
I know this is an old post, but I don't like any of the answers, so for future readers.我知道这是一篇旧文章,但我不喜欢任何答案,所以对于未来的读者。
When you cast an object to a void*, you loss the type information associated with it.当您将 object 强制转换为 void* 时,您会丢失与其关联的类型信息。 That is why you can't use sizeof with a void* ptr.这就是为什么您不能将 sizeof 与 void* ptr 一起使用。 (This is probably also why memcpy doesn't do it this way). (这可能也是 memcpy 不这样做的原因)。 I think what you need here is to write a Template class.我认为您需要在这里编写一个模板 class。 Then the code will know the type and the code should work.然后代码将知道类型并且代码应该可以工作。
template<class T>
class object
{
public:
void setData(T *ptr);
T* data;
};
void object::setData(T *ptr)
{
assert(ptr);
memcpy(data, ptr, sizeof(ptr));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.