컴파일러 구조체 패딩 이슈

임정환·2023년 8월 7일
0

진짜 간단한 과제인데 , 우리 g++ 컴파일러의 구조체 패딩덕분에 약 6시간을 삽질...

struct BootRecord{
    u_char jump_boot_code[3];
    u_char oem_name[8];
    u_short bytes_per_sector;
    u_char sector_per_cluster;
    u_short reserved_sector_count;
    u_char number_of_fat;
    u_short root_dir_entry_count;
    u_short total_sector_16;
    u_char media;
    u_short fat_size_16;
    u_short sector_per_track;
    u_short number_of_heads;
    u_int hidden_sector;
    u_int total_sector_32;
    u_char drive_number;
    u_char reserved1;
    u_char boot_signature;
    u_int volume_id;
    u_char volume_label[11];
    u_char file_system_type[8];
};

FAT32 파싱 코드를 짜는데 이상하게 sizeof(BootRecord)를 사용하니 64바이트가 아니라
68바이트가 나왔다.
나는 당연히 구조체의 데이터 집합이 64바이트이므로 image파일에서 64바이트를 read했을 줄 알았다.
하지만, 컴파일러는 WORD 단위로 Read와 Write를 하기때문에 만일 애매한 자료형들이 존재한다면 바로 패딩을 넣어서 자신이 읽고쓰기 편하게 바꿔버린다.
일반적인 프로그래밍이면 별 문제 안되지만 , 나는 byte시퀀스 단위로 파싱을해야하기 때문에 굉장히 크리티컬 했다는점...
네트워크 프로그래밍에서 특히나 신경써줘야하는 부분이다.

해결방안

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdint.h>
#pragma pack(push, 1) // 컴파일러에게 구조체를 1로 정렬하라고 지시 
#define RESERVED_SECTOR_COUNT_OFFSET 14
#define FAT32_SIZE_32_OFFSET 36
#define BYTE_PER_SECTOR_OFFSET 11
#define SECTOR_PER_CLUSTER_OFFSET 13

위처럼 pragma pack을 통해서 컴파일러에게 1바이트 구조체 정렬을 지시했다.

profile
CS 박제

1개의 댓글

comment-user-thumbnail
2023년 8월 7일

글 재미있게 봤습니다.

답글 달기