2010-07-19 3 views
2

저는 C++의 학습 과제로 간단한 TGA 이미지 파일 세이버를 작성하려고합니다. 헤더에 대한 구조체를 선언 한 다음 fread()를 사용하여 전체 헤더를 한 번에로드하는 예제 TGA 로더에 코드를 적용합니다.구조체를 파일에 쓸 때 너무 많은 바이트가 쓰여집니다.

내 프로그램이 현재 작동하지 않으며 파일에 두 개의 여분의 바이트가 기록되어있는 것처럼 보입니다. sizeof 제 구조체를 인쇄하고 두 바이트가 너무 큽니다 (정확한 18 대신 20). 약간의 독서 후 문제는 데이터 정렬 및 패딩과 관련이 있다고 생각합니다 (구조체를 저장하는 방법에 익숙하지 않습니다).

제 질문은이 문제를 해결하는 좋은 방법입니다. 내가 구조체의 구성 요소를 바이트 단위로 작성하는 대신 fwrite()를 사용하여 전체 구조체를 한 번에 쓸 수 있다고 생각한다. 나는 헤더를로드 할 때 작동한다면, 그것을 쓸 때도 작동한다고 생각했다. 내 가정이 틀렸어?

답변

4

컴파일러는 필드가 적절한 메모리 주소에 정렬되도록 구조에 패딩 바이트를 삽입 할 수 있으며 자주 수행합니다.

가장 간단한 해결책은 구조체를 "팩"하도록 컴파일러에 지시하는 것입니다. 즉, 패딩 바이트를 삽입하지 않는 것입니다. 그러나 이렇게하면 구조에 대한 데이터 액세스가 더 느려지 며이를 수행하는 방법은 컴파일러에 따라 다릅니다. 이식성 있고 효율적으로되고 싶다면, 필드를 개별적으로 작성하는 것만이 유일한 방법입니다.

1

로드하는 중에도 작동하지 않았습니다. 몇 가지 옵션이 있습니다.

  1. 컴파일러 관련 지시문 (#pragma packed 등)을 사용하여 구조가 18 바이트가되도록합니다.

  2. 버퍼 필드를 가져 오거나 설정하기위한 오프셋과 포인터를 사용하여 이식성이 뛰어난 코드를 작성하십시오.

0

구조체의 요소는 일반적으로 4 바이트 경계에 배치됩니다.

구조체에 short 나 char가있는 경우 구조체가 개별 요소 크기의 합보다 큽니다.