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
여기 맨 아래 답변 참고
댓글 없음:
댓글 쓰기