다음 코드를 사용하여 일반 사용자 지정 구조를 직렬화 / 비 직렬화하는 데 사용하려는 일반 직렬화 메서드를 구현하려고합니다.
#include <string>
#include <iostream>
class MessageSerializer
{
public:
MessageSerializer(){}
~MessageSerializer(){}
template <typename Data>
std::string serialize(const Data data)
{
const char* lpData = reinterpret_cast<const char*>(&data);
std::string serializedData( lpData, sizeof(data));
return serializedData;
}
template <typename Data>
void deSerialize( const std::string &serializedData, Data &deserializedObject )
{
const size_t serializedDataSize = serializedData.size();
const size_t outputDataSize = sizeof(Data);
if ( serializedDataSize != outputDataSize ){
std::cout << "Failed size check" << std::endl;
}
std::copy(std::begin(serializedData), std::end(serializedData), reinterpret_cast<char*>(&deserializedObject));
}
};
#pragma pack(push, 1)
struct testStruct
{
testStruct(int a, double f, std::string text, char c) : _a(a), _f(f), _text(text), _c(c){}
testStruct(){}
int _a;
double _f;
std::string _text;
char _c;
};
#pragma pack(pop) ```
내 메인에서 사용할 때 :
#include "serializer.hpp"
#include <iostream>
#include <string>
int main ()
{
MessageSerializer ser;
testStruct sender(1, 345.234, "this is a test string", 'h');
testStruct receiver;
std::string msg = ser.serialize(sender);
std::cout <<"serialized: " << msg << std::endl;
std::cout << "-------------" << std::endl;
ser.deSerialize(msg, receiver);
std::cout << "received content: \na= " << receiver._a
<< "\nf: " << receiver._f
<< "\ntext: " << receiver._text
<< "\nc: " << receiver._c << std::endl;
return 0;
}
내 메인이 끝나면 다음과 같은 오류 메시지가 표시됩니다.
free () : tcache 2에서 이중 해제가 감지되었습니다. 중단됨 (코어 덤프 됨)
정확한 원인을 찾을 수없는 것 같습니다. 몇 가지 조사를 마친 후 두 번째로 할당되지 않은 리소스가 두 번 해제되고 있음을 이해하지만 힙에 아무 메모리도 할당하지 않습니다.
아무도 내 문제의 원인을 이해하도록 도와 줄 수 있습니까?
내가 생각할 수있는 한 가지 문제 sizeof(testStruct)
는 실제로 포함 된 각 요소 유형의 크기와 거의 동일 하다는 사실입니다 .
sizeof(int) + sizeof(double) + sizeof(std::string) + sizeof(char)
결과 크기는 std::string
객체 의 실제 내용 () 전체를 포함하지 "this is a test string"
않지만 대신 testStruct
포함 하는 기본 데이터 유형 의 크기에 포함 된 기본 데이터 유형 의 크기 std:string
( 내용 자체가 아닌 내용에 대한 포인터).
따라서 testStruct
by 값을 serialize
메소드에 전달하기 때문에 메소드 "this is a test string"
종료시 포함 된 std::string
객체를 파괴하면 해제 될 문자 시퀀스에 대한 포인터를 복사 serialize
하는 것과 같을 것이며, 동일한 포인터는 다음과 같은 경우에도 해제 될 것입니다. 프로그램이 종료됩니다 (왜냐하면 메인에서도 sender
의 std::string
객체 로 선언되기 때문입니다 ).
당신은 당신의 포장 std::string
로 testStruct
구조체 (소멸자를 가지고있는?)하지만 그냥 단지 일반으로 테스트하는 경우 이것은 아마도 발생할 수있는 std::string
당신과 같은 오브젝트 sender
값.
이것이 일어나고있는 것처럼 보이지만 완전히 확실하지 않으므로 가정 / 가설에서 내가 틀렸다면 수정하십시오.
첫 번째 의견에 대한 답변으로 : char*
텍스트의 내용이 다시 복사되지 않을 것임을 의미하기 때문에 텍스트에를 사용할 수 없습니다 . 실제 포인터의 값만 인코딩됩니다. 고정 된 크기 의 char
배열 (예 : say 또는 something)을 사용하고 거기에 텍스트를 저장할 수 있지만 다음과 같습니다.char[100]
testStruct
.
https://isocpp.org/wiki/faq/serialization 링크를 살펴보고
조금 읽어 보시기 바랍니다 . 도움이 될 수 있습니다.
텍스트 표현 (예 : XML 또는 일반 사용자 정의 구조 텍스트)을 원하는 경우 다시 이식 할 수 없다는 점을 기억하십시오. 예를 들어 int
값 (예 : 2 ^ 30) 으로 여러 유형을 인쇄하면 다른 int
크기가 2 바이트 인 아키텍처에서는 값이 오버플로됩니다. 그러나 아마도 cstdint 유형 (예 : 등) 으로이 문제를 해결할 수 int_least32_t
있지만 모든 데이터를 숫자로 인코딩해야합니다. 너무 어렵지 않을 수도 있고 그렇지 않을 수도 있습니다. 특정 텍스트 인코딩 테이블 (예 : ASCII, UTF-8 등)을 사용하는 것을 의미합니다.
C ++에서 객체를 직렬화하는 방법에 대한 다른 게시물을 볼 수도 있습니다 .
바이너리 표현과 이식성과 쉬운 구현을 원한다면 가능한 한 언어를 Java로 변경 한 다음 Serializable
인터페이스와 규칙을 살펴 보는 것이 좋습니다 . Java와의 차이점은 고정 된 크기의 원시 데이터 유형이 있고 내가 아는 한 아키텍처에 의존하지 않는다는 것입니다.
동일한 프로세스에서 복잡한 개체 만 복사하려면 복사 생성자를 사용합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다