##質問概要
・オブジェクト Data
のシリアル化と逆シリアル化を行う関数を作成しています。しかし、オブジェクトのシリアル化をした後に、逆シリアル化を行うと、シリアル化した際のメモリレイアウトがずれてしまい、正しく逆シリアル化できないのですが、どうしてそうなってしまうのかわかりません。お力を貸してください。
##質問詳細
環境は、
機種名: MacBook Air
機種ID: MacBookAir8,2
プロセッサ名: Dual-Core Intel Core i5
プロセッサ速度: 1.6 GHz
プロセッサの個数: 1
コアの総数: 2
二次キャッシュ(コア単位): 256 KB
三次キャッシュ: 4 MB
ハイパー・スレッディング・テクノロジ: 有効
メモリ: 8 GB
です
今回、シリアル化したいオブジェクトは、以下のものです
C++
1typedef struct Data 2{ 3 std::string s1; 4 int n; 5 std::string s2; 6} Data; 7
このオブジェクトに関して void *serialization(std::string s1, int num, std::string s2)
でシリアル化した後、 Data *deserialization(void *raw)
で逆シリアルかすることを考えます
実際のコードと、それをテストした結果をいかに示します。
###実行コード
C++
1// main.cpp 2 3#include <iostream> 4#include <string> 5 6typedef struct Data 7{ 8 std::string s1; 9 int n; 10 std::string s2; 11} Data; 12 13// serialization 関数名で、先に52バイトメモリを確保し、キャストしながらメモリに値を配置していく 14void *serialization(std::string s1, int num, std::string s2) 15{ 16 void *ret = reinterpret_cast<void*>(new char(52)); 17 void *tmp; 18 std::string *p_s1; 19 int *p_num; 20 std::string *p_s2; 21 22 p_s1 = reinterpret_cast<std::string*>(ret); 23 std::cout << "p_s1 = " << p_s1 << std::endl; 24 *p_s1 = s1; 25 p_s1++; 26 p_num = reinterpret_cast<int*>(p_s1); 27 std::cout << "p_num = " << p_num << std::endl; 28 29 *p_num = num; 30 p_num++; 31 p_s2 = reinterpret_cast<std::string*>(p_num); 32 std::cout << "p_s2 = " << p_s2 << std::endl; 33 34 35 *p_s2 = s2; 36 37 return (ret); 38 39} 40 41Data *deserialization(void *raw) 42{ 43 Data *ret; 44 ret = reinterpret_cast<Data*>(raw); 45 return (ret); 46} 47 48int main() 49{ 50 51 std::cout << "\n\n======================Serialized Raw Data========================\n\n" << std::endl; 52 53 void *p = serialization("testtest", 42, "testtest"); 54 55 56 std::cout << "\n\n======================Deserialized Raw Data========================\n\n" << std::endl; 57 58 Data *data = deserialization(p); 59 60 std::cout << "p_s1 = " << &data->s1 << std::endl; 61 std::cout << "p_s1 = " << &data->n << std::endl; 62 std::cout << "p_s1 = " << &data->s2 << std::endl; 63 std::cout << data->s1 << std::endl; 64 std::cout << data->n << std::endl; 65 std::cout << data->s2 << std::endl; 66} 67 68
###実行結果
% clang++ main.cpp % ./a.out ======================Serialized Raw Data======================== p_s1 = 0x7f9388c05910 <- 10 (16) p_num = 0x7f9388c05928 <- 28 (40) (std::string の24byte分メモリが進んだ) p_s2 = 0x7f9388c0592c <- ここは、2c(44) なのに (int の 4byte分メモリが進んだ) ======================Deserialized Raw Data======================== p_s1 = 0x7f9388c05910 <- 10 (16) p_s1 = 0x7f9388c05928 <- 28 (40) p_s1 = 0x7f9388c05930 <- ここは、30(48) に変わって4バイト分余計にずれている testtest 42 test <- 値も失われている
####まとめ
このように、シリアル化してから逆シリアル化するさいにメモリがずれデータが失われるのはなぜでしょうか...
自分の予想としては、逆シリアル化するさいに単純なreinterpret_cast をしているのが問題なのかな と予想してますが、何が問題なのかわかりません。
Data
オブジェクトの3つのメンバはメモリ上に一列に配置されるので、シリアライズされ送られてきたポインタをキャストすれば逆シリアル化できると思ってました。
違うようです...
ご教授くださいm(_ _)m
補足
Data
オブジェクトの std::string には、最大で小英数字8 文字までしかいれない前提があります。。
なので、std::string を 24byte として決め打ちしてます
回答3件
あなたの回答
tips
プレビュー