C에서 구조체 속 패딩 데이터 접근시 문제에 대해서 질문 합니다.
글쓴이: ikpil / 작성시간: 금, 2010/04/02 - 2:08오후
안녕하세요? Modern C++ Design 책을 보고 있는데, 이해가 안가는것이 있어서 이렇게 질문을 올립니다.
구조체 속에 패딩 공간이 생긴다는 것은 알고 있습니다.
이 패딩 공간을 쓰기 위해서, 형변환하여 사용 하면, 문제가 발생 되나요?
실제로 테스트 해보았는데, 아무 이상이 없음에도,
책에선 단지 위험하다고만 설명 되어 있습니다.
본문 내용 중 우리는 메모리 정렬 문제(32bit 컴퓨팅 환경의 컴파일러의 경우, 최적화를 위해 대부분 4byte 단위로 자료형을 끊어서 다루게 됩니다. 예를 들어, char 와 int 자료형이 섞여 있는 구조체의 경우를 살펴보면, char 자료형에서 실제 사용되는 정보는 1byte 뿐이지만, 메모리 할당에 있어서는 int와 같은 4byt가 할당되는 경우가 생긴다는 것입니다. 구조체를 디자인할 때에는 이 같은 문제를 항상 유의해야 합니다)에 대해서 생각해 보아야 합니다. 5byte 크기의 블록에 대한 할당기를 구성하는 경우를 생각해 봅시다. 이 경우에, 이 블록을 가리키는 포인터를 unsigned int 로 형변환하는 작업은 예기치 못한 동작을 초래하게 됩니다. 이것은 상당히 심각한 문제가 될 것입니다.
이 뜻을 "패딩 공간을 임의로 쓸 경우, 그 공간이 변경 되는 것을 예측 할 수 없기 때문에 위험하다."로 해석해도 될까요?
Forums:
패딩공간 만드는거는
패딩공간 만드는거는 사용하는 아키텍쳐 제역 + 컴파일러에 따라 달라집니다.
패딩공간 안만들 수 있으면 안만드는 컴파일러도 있을 수 있고,
타 아키텍처로 포팅할때 해당 아키텍처에서 만들어지는 패딩공간 길이가 달라질 수 있고.
본인 시스템에서 본인 컴파일러로 한다면 문제는 안되겠지만, 타 컴파일러 쓸 수 밖에 없다거나 아니면 타 시스템으로 넘기는 경우도 있을 수 있으니 고려를 해야죠.
Written By the Black Knight of Destruction
Written By the Black Knight of Destruction
그렇군요. 이 경우도
그렇군요. 이 경우도 있었네요.
책에서 말하는 내용이 이 경우인 것 같습니다.
short + char 만 할당 시켰는데, 패딩공간이 생길 줄 알고, int 로 형변환해서 사용 했더니
실제로 3byte만 할당 되어 버려서, 다른 메모리 침범되는 경우가 생기겠군요.
.. 감사합니다. 간지러웠던 곳을 긁을 수 있었습니다.
http://www.ikpil.com
http://www.ikpil.com
곰곰히 생각해
곰곰히 생각해 보니
3Btye 이하에 대해서만 발생 될 수 있는 문제군요.
그러므로 5Btye 이상에서
발생 될 수 있는 문제는 "패딩 공간에 있는 값이 프로그래머의 의도와 상관없이 변경될 수 있느냐?" 입니다.
http://www.ikpil.com
http://www.ikpil.com
...
<<< 이 패딩 공간을 쓰기 위해서, 형변환하여 사용 하면, 문제가 발생 되나요? >>>
구체적인 예를 들어주시면 좋겠네요.
그리고 제 의견을 먼저 이야기하자면.......
일단 패딩으로 낭비되는 공간이 얼마나 있는지 분석이 필요합니다. padding 은 프로세서가 메모리를 읽을 때 속도 최적화를 위해서 하는 것이거든요.
32 bit OS 에서는 32 bit 단위로 끊어 읽을 때 가장 속도면에서 최적이니까요.
패딩 공간을 줄여보자고 할때는 그런 속도에 대한 잇점을 포기할 당연한 이유가 전제가 되어야 겠지요. <<만약 수십메가 ~ 수백메가의 메모리/파일 공간을 절약할 수 있다>>고 한다면 모르겠으나 수백 kbytes 를 절약하는 것이라면... 굳이 할 필요가 없겠죠.
어디서 듣기로는 주로 패딩을 없애는 작업은 네트워크 통신 프로그램 같이 최대한 패킷 사이즈를 줄여야 할 경우에 사용하는 것으로 들었습니다.
패딩 없애는 경우 1.
패딩 없애는 경우
1. 파일 읽고 쓰기.
-> 여러 시스템에서 잘 읽혀지기 위해서는 바이트 단위로 해당 파일 포맷에 맞춰 정확하게 읽혀져야 하고 쓸 수 있어야 합니다. 중간에 이유없이 패딩 들어갈수 있게 하면 패딩크기가 다른 시스템에서는 인식 못하죠.
2. 네트워크 통신
-> 파일과 같습니다. 패킷사이즈가 문제가 아니라 여러 종류 시스템에서 규격이 정해진 각종 프로토콜 포맷(ip header, tcp header 등등)을 똑같이 인식하기 위해서입니다.
파일 포맷 사이트에서 샘플로 GIF 포맷 문서 받아서 보세요. 헤더는 크기 몇바이트에 몇번째 오프셋에 무슨 정보가 있고.... 포맷은 그런식으로 명확하게 규정되어 있습니다. 파일의 어디 중간에 포맷에 규정되지 않은 임의길이 패딩을 넣으면, 같은 시스템에서는 어찌 읽을 수 있겠지만 타 시스템에서는 그것을 제대로 해석 못하게 됩니다.
Written By the Black Knight of Destruction
Written By the Black Knight of Destruction
//구체적인 예 struct
//구체적인 예
struct testpadding
{
char a;
int i;
}
testpadding dummy;
dummy.i = 10;
int *pa = (int *)&dummy.a;
*pa = 3;
이렇게 했을 때, (int *)&dummy.a 는 계속 참조를 하여도, 3 입니다.
제가 궁금한 것은
컴파일 환경에 따라서 (int *)&dummy.a 의 값이 3이 아닐 수 있는가? 입니다.
하지만 윗분에 말씀 주신, 컴파일 환경에 따라서 값이 변경 될 수 있다를 알았습니다.
http://www.ikpil.com
http://www.ikpil.com
[bushi@rose pad]$ cat
byte align 문제에 byte order 예를 드는 게 적절치 못하고, 더 헷갈릴 수도 있다는 생각이 들긴하지만,
구체적인 예라고 드신 게... 지구 상에 존재하는 모든 C 컴파일러가 무조건 4byte align 으로 대동단결을 한다하더라도... 쓸 수 없는 코드라는 걸 말씀드리려니 이것밖에 없네요.
OTL
바이트 오더를
바이트 오더를 이렇게 실제 예로 증명해주신 분은 처음입니다.
재미있게 잘 보았습니다.
감사합니다.
http://www.ikpil.com
http://www.ikpil.com
댓글 달기