[英]Why doesn't this memcpy work?
所以我有以下代碼,我想做的簡化版本。 我有一個 class 的成員變量,我想根據情況將其設置為可能的各種不同的數據類型(我只是為此測試創建了一個隨機結構)。 我一直在 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;
}
您的代碼有多個問題,但是SIGSEGV的直接原因是以下行: memcpy(data, ptr, sizeof(ptr));
它試圖將多個字節復制到未分配的指針data
。
附帶說明一下,您似乎正在嘗試使用完全不合適的方法在C ++中實現多態。
其他人提到memcpy
是不正確的,因為使用sizeof(void*)
作為要復制的字節數。 但是將sizeof
更改為適當的值只會使您使用memcpy
到達下一個絆腳石。 執行此行后,您可能會遇到它:
cout<<test.data->name<<endl
原因是data->name
很可能已損壞,無效,或者如果確實看到了打印的名稱,則字符串處於不穩定狀態。
基本上,如果該結構不是POD類型,則使用memcpy
將結構設置為某個值將不起作用。
您的product
類具有一個非POD類型的成員,即std::string
。 你不能簡單地疊加一個std::string
對象從另一個數據字節std::string
對象(這是什么memcpy
會做)。
對於諸如memset
函數或任何設置值所指向的字節的面向C
的函數,都可以說相同的話。 它們不能用於非POD類型。
與POD類型不同,僅執行類似的字節副本將損壞目標對象。 如果包含該對象(例如v表),那么您實際上將把目標對象撕成碎片。
對於非POD類型,請使用適當的C ++技術,其中包括使用賦值( data = ptr
)。
我也想這可能是個問題
cout<<test.data->name<<endl;
案例數據為空指針,因此您需要在此處進行投射
cout<<static_cast<product *>(test.data)->name<<endl;
我知道這是一篇舊文章,但我不喜歡任何答案,所以對於未來的讀者。
當您將 object 強制轉換為 void* 時,您會丟失與其關聯的類型信息。 這就是為什么您不能將 sizeof 與 void* ptr 一起使用。 (這可能也是 memcpy 不這樣做的原因)。 我認為您需要在這里編寫一個模板 class。 然后代碼將知道類型並且代碼應該可以工作。
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.