user14253131
user14253131

Reputation:

std::copy issue I don't knowwhy this error happens

  1. I copied the struct into a vector and put it back into the struct. Why did this bug occur? use std::copy incorrectly?

  2. When copying, I used std::copy, and I copied structures one by one.

This is the code:

struct test_msg
{
  int32_t msg_type =0; 
  int32_t msg_id =0; 
  int32_t src = 0 ; 
  int32_t dst = 0;

  std::string data;

  bool Serialize(std::vector<char> &out) {
    out.clear();
    std::copy(&msg_type, &msg_type + sizeof(msg_type), std::back_inserter(out));
    std::copy(&msg_id,&msg_id + sizeof(msg_id), std::back_inserter(out));
    std::copy(&src,&src + sizeof(src), std::back_inserter(out));
    std::copy(&dst,&dst + sizeof(dst), std::back_inserter(out));

    std::copy(json_string.begin(),json_string.end(), std::back_inserter(out));

    return true;
  };

  bool Deserialize(std::vector<char> &out) {
    int last_index = 0;

    std::copy(out.begin() + last_index, out.begin() +last_index + sizeof(msg_type), &msg_type);          last_index += sizeof(msg_type);
    std::copy(out.begin() + last_index, out.begin() +last_index + sizeof(msg_id), &msg_id);              last_index += sizeof(msg_id);
    std::copy(out.begin() + last_index, out.begin() +last_index + sizeof(src), &src);                    last_index += sizeof(src);
    std::copy(out.begin() + last_index, out.begin() +last_index + sizeof(dst), &dst);                    last_index += sizeof(dst);
   // std::copy(out.begin() + last_index, out.begin() +last_index + sizeof(synchronous), &synchronous);    last_index += sizeof(synchronous);
    std::copy(out.begin() + last_index, out.end(),  std::back_inserter(json_string));

    return true;
  };
};
int main(int argc, char *argv[]) {
  testmsg msg;
  msg.msg_type =11;
  msg.msg_id =22;
  msg.src =33;
  msg.dst =44;
  msg.json_string = "this is test!this is test!this is test!\0";

  std::vector<char> data;
  msg.Serialize(data);

  IpcJsonMessage msg2;
  msg2.Deserialize(data);

  return 1;
}

Upvotes: 0

Views: 67

Answers (1)

Den-Jason
Den-Jason

Reputation: 2573

The issue is that you're using std::copy to copy int32s which will iterate int32s but you're thinking it will iterate bytes:

std::copy(&msg_type, &msg_type + sizeof(msg_type), std::back_inserter(out));

In this case you will most likely be copying 4 non-contiguous bytes - from offsets 0, 4, 8, 12 (LSB first), since the iteration will work in the same fashion as when you're incrementing C pointers (i.e. int32* pX; pX++; will increment pX by one int32 -> 4 bytes). Each iteration will load an int32 from memory but only add the least significant byte to the char vector.

It helps to think of how the std::copy unrolls:

int32* pIter;
int32* pEnd;   //pIter+4 i.e 16 bytes ahead of pIter
vector<char> dest;

while (pIter < pEnd)
{
    int32 value = *pIter;
    dest.push_back (value);  //loses the upper 24 bits of value
    pIter++;
}

See here for a full explanation: Copy Memory to std::copy

Here is a screendump from running a snippet in Visual Studio:

enter image description here


In terms of a solution to the problem, take a look at: Is it possible to serialize and deserialize a class in C++?

Upvotes: 3

Related Questions