예전에 했던 포인터로 캡슐화를 깨보자! 에서 파생된 건데 생각한 것 만큼 잘 안되네요 -_-;;
프갤흰님들의 도움이 필요한 부분입니다.
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 | #include <iostream> using namespace std; class Widget { public: Widget(int val, char ch, unsigned short num, char* str) :_val(val),_ch(ch),_num(num) { int length = strlen(str) + 1; _str = new char[length]; strcpy(_str, str); } ~Widget() { delete[] _str; } virtual void VirtualFunc() { cout << "I'm the first virtual function " << endl; } private: int _val; char _ch; unsigned short _num; char* _str; }; int main(void) { Widget w(128,'a',64, "ABCD"); char* pw = reinterpret_cast<char*>(&w); printf("%d ", *(int*)(pw + 4)); printf("%c ", *(char*)(pw + 8)); printf("%d ", *(unsigned short*)(pw + 9)); printf("%s ", *(char**)(pw + 11)); return 0; } | cs |
위에는 제가 생각한 Widget w의 메모리 구조인데 -_-; 잘 안되네요.
*(unsigned short*)(pw+10)
*(char**)(pw+12);
로 바꾸니까 잘 되긴 하는데
왜 왜 +9가 아니라 +10인지 몰겠심덩..
노무어려워서 ㅁㅈㅎ
컴파일러마다 다른데, 요즘 null structure 가 1바이트인 컴파일러들이 많음.
그거랑 memory align 문제랑 따져보면 답이 나오겠쥬~ 멤버함수 하나 만들어서 offsetof 찍어보면 됨
제가 안는 null structure는 음.. 그냥 struct로 만든 구조체에 아무것도 {0}; 이런식으로 초기화를 해버리는 것으로 알고있는데
여기서 어떻게 이어지나요...?
_ch 는 1바이트를 차지하고 있을 수 없음요.
그다음의 _num 은 shot 타입이라 주소가 2의 배수이도록 정렬되는게 기본임.
즉 _ch 와 _num 사이의 차가 2 가 됨.
int 는 주소가 4의 배수이도록 정렬되고 double 은 주소가 8의 배수이도록 정렬되기 때문에, 앞 자료형과의 사이에 공백이 생길수 있습니다. 크기가 딱딱 떨어지지 않으면.
그걸 memory align 문제라고 하고, pack 같은 preprocessor directive 로 지정하든지, 아니면 감안한고 작성하셔야함다~
감안하고.
아하
memory align이 이렇게 등장하다니 -_-~
offsetof라는 것도 있군요 한 번 써볼게요
오호 offsetof를 적용하니까 바로 10이 나오네요 ㅋ.ㅋ
그건 컴파일러에 따라 있기도 하고 없기도 한 매크로인데, this* 로 0을 캐스팅 해서 멤버를 구하는것이쥬~
다만.. private인 경우엔 접근이 불가능해서 public으로 잠깐 바꿔줘야하는 단점이 있네요.. ㅜ