2020년 7월 1일 수요일

std::vector 에러 없에 binary 로 뽑기

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

// 실험용.cpp : This file contains the 'main' function. Program execution begins and ends there.

//

#include "pch.h"

#include <iostream>

#include <Windows.h>

#include <string>

#include <vector>

#include <fstream>

//무조건 std::vector 는 struct 의 맨 뒤에 있어야함.

//std::vector 의 크기는 16 byte.

struct AAA

{

AAA() { 1 == 1; }

~AAA() { 1 == 1; }

int a;

int b;

};

struct BBB

{

BBB() { 1 == 1; }

~BBB() { 1 == 1; }

int a;

int b;

std::vector<AAA> aaas;

};

template<typename T>

int GiveTotalByteOfStruct() { return 0; }

#define RegisterStructForVectorSize(T, num) template<> int GiveTotalByteOfStruct<T>() { return sizeof(T) - num*16;}

RegisterStructForVectorSize(AAA, 0)

RegisterStructForVectorSize(BBB, 1)

template<typename T>

void WriteVector(const std::vector<T>& vector, std::ofstream& fout)

{

int length = vector.size();

fout.write((char*)&length, sizeof(int));

for (int i = 0; i < length; i++)

fout.write((char*)&vector[i], GiveTotalByteOfStruct<T>());

}

template<typename T>

void ReadVector(std::vector<T>& vector, std::ifstream& fin)

{

int length;

fin.read((char*)&length, sizeof(int));

vector.reserve(length);

vector.resize(length);

for (int i = 0; i < length; i++)

fin.read((char*)&vector[i], GiveTotalByteOfStruct<T>());

}

void main()

{

std::vector<BBB> bbbs;

for (int i = 0; i < 3; i++)

{

BBB bbb;

bbb.a = i; bbb.b = i * 2;

for (int j = 0; j < 4; j++)

{

AAA aaa;

aaa.a = 1+i; aaa.b = j * 2;

bbb.aaas.emplace_back(aaa);

}

bbbs.emplace_back(bbb);

}

std::ofstream fout("temp.dat", std::ios::out | std::ios::binary);

{

WriteVector(bbbs, fout);

for (int i = 0; i < bbbs.size(); i++)

WriteVector(bbbs[i].aaas, fout);

}

fout.close();

for (auto& bbb : bbbs)

{

std::cout << bbb.a << bbb.b << bbb.aaas[0].a << std::endl;

}

std::cout << "끝났음" << std::endl;

bbbs.clear();

bbbs.shrink_to_fit();

std::ifstream fin("temp.dat", std::ios::in | std::ios::binary);

{

ReadVector(bbbs, fin);

for (int i = 0; i < bbbs.size(); i++)

{

ReadVector(bbbs[i].aaas, fin);

}

}

fin.close();

for(auto& bbb : bbbs)

{

std::cout << bbb.a << bbb.b << bbb.aaas[0].a << std::endl;

}

std::cout << "끝났음" << std::endl;

return;

};

정확히 말하면 멤버변수 중에 std::vector 가 있는 경우.

이런 애들은 메모리를 덮어 쓰면 안됨.

내부 포인터까지 덮어쓰면, 소멸자호출 할 때 무조건 에러뜸.

이부분을 제외하고 저장한 후, 읽을 때도 그렇게 해야함.

https://stackoverflow.com/questions/14089266/how-to-correctly-write-vector-to-binary-file-in-c

여기 맨 아래 답변 참고

댓글 없음:

댓글 쓰기

List