[t:/]$ 지식_

포인터와 메모리 얼라인

2008/10/27

옛날에 써 놓은 글 아까워서 복구.

일반적인 32비트 임베디드 머신에서..
(하드웨어 얼라인먼트가 제공되지 않는)

int aa[100]  
int *a 가 있을때  
a = aa 라고 치고...  

*(a + 1) == *(int *)(&aa[0] + sizeof(int)) == *(int *)(&aa[0] + 4)

여기까지는 다들 잘씀..

unsigned int *ii;  
unsigned char *ppp = 0x4000;  

ppp++;  // 0x4001 번지를 가리킴

ii = (unsigned int *)ppp;   // 메모리 얼라인 에러, ii는 0x4001을 가리킬 수 없음.

메모리 얼라인이 꼬이면 현상은 다양하다.
컴파일러와 CPU와 버스 설계에 따라서 데이터 어봇이 뜨기도 하고,
그냥 4의 배수 주소 이하는 패딩시켜버리고 자동 인식하기도 하고 해서..

절대 이렇게 쓰지 말라고 한다.... 라고는 하는데.
거의 대부분은 패딩됨.

즉.

*(char *)0x4000 == *(int *)0x4001 == *(int *)0x4002 == *(int *)0x4003

이런경우가 많음.
차라리 에러라도 뜨면 속편한데 잠재적 문제점으로 잠자는 경우도 많다.

예를 들어 스트림 버퍼를 처리할 때 버퍼 부분은 거의 4바이트 워드 단위로 처리하는데, 헤더 푸터는 막 short 형 등장이요. 하면 종종 버그터진다.

구조체를 packed 시켜서 각각의 엘리먼트 정의를 해놓고 쓰면 좋은데.
세상만사 귀찮은 일이 한 둘이어야지.

사실 void * 형으로 몽창 보내고 받고 구조체 캐스팅 펑 때리는 것 처럼 C언어가 사랑스러울 때가 또 없다.

알다시피, 물론 여기서 메모리 얼라인, 엔디안 문제 제일 많이 터진다. ㄲㄲㄲㄲ;;









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