[t:/]$ 지식_

void 포인터와 메모리 얼라인

2008/11/26

예전 글 복구 재게시.

. . .

MP3 디코딩 엔진 포팅을 하나 하다가.. 헤멘 부분 기록.
문제가 발생하는 상황은 다음과 같다.

뭐 대충 쓴 코드니까 상세는 보지 말고 원리만...

unsigned int r;  
unsigned int *p = (unsigned int *)0x3000....    // 최초에 정의된 포인터, 4바이트 얼라인  

unsigned char *pp;         // 1바이트 얼라인..  
pp = (unsigned char *)p;  // 문제 없음..  

pp++;  // 바이트 증가, 현재 4바이트 얼라인에 맞지 않음.  

r = yyy((void *)pp);        // void 포인터로 전달.  

. . .

unsigned int yyy(void *var)  
{  

        return (unsigned int)(*var);   
        // 익셉션 뜨고 시스템 정지.  
        //4바이트 얼라인에 맞지 않기 때문.  

}  

// 에러 안 나는 함수 쉽게 풀어 써 봄.

unsigned int yyy(void *var)  
{  
        unsigned int r;  
        unsigned char *temp;  // 1바이트 얼라인 가능!!!!  

        temp = (unsigned char *)v;                 

        r  = *temp++ << 24; // 엔디안에 따라 바이트 순서는 서로 다름.  
        r |= *temp++ << 16; // 1바이트 얼라인 가능  
        r |= *temp++ << 8;  
        r |= *temp++ << 0;  

        return r;  
}  

// 퀴즈1. 한 줄로 줄여보자.
// 퀴즈2. 인라인 어셈으로 줄여보자.

void *형 포인터를 쓸 때는 항상 바이트 얼라인에 중요하자. 구조체 캐스팅 시에 이빨빠진 더미 공간도 항상 조심!!

gcc 에서 __attribute(..packed.. 어쩌구... 혹은 vc 계통에서 #pragma... 어쩌구 와는 달리. ads에서는 다음과 같이 한다.

typedef __packed struct  
{  
        UINT32 fcc;  
        UINT32 cb;  
        UINT16  wFormatTag;  
        UINT16  nChannels;  
        UINT32 nSamplesPerSec;  
        UINT32 nAvgBytesPerSec;  
        UINT16  nBlockAlign;  
        UINT16  wBitsPerSample;  
} WAVEFORM;  

20세기 개발자 : 데이터가 칸칸이 나뉘어진 기차처럼 보임.
20세기말 개발자 : 데이터가 한 량에 4칸인 기차처럼 보임.
21세기 개발자 : 데이터가 보자기로 묶은 객체로 보임.

난 20세기말 개발자다 -_-;









[t:/] is not "technology - root". dawnsea, rss