Test/C

메모리와 포인터3 : 메모리 동적 할당 및 관리

kiostory 2018. 12. 19. 19:10

* 메모리

- 종류

. stack : 1MB 정도 : 함수, 일반 변수 등

. heap : 자유 영역 , 동적 할당과 관련

. 32bit application, console 프로그램일 경우 : 1.7GB 정도

. PE image

. text 영역 : 코드

. data 영역

. RW : 전역변수, 정적변수

. R : 문자열 상수가 위치하게 됨


* 메모리의 동적 할당?

. OS가 관리하는 메모리

. stack 크기를 넘는 메모리 필요시, OS가 프로그램에 메모리 영역을 사용할 수 있도록 '허가' 해주게 됨

. 사용 후 반환. 따라서 언제 어디서 사용할 지, 언제 반환할지 고민이 필요함

. heap 영역을 사용하게 됨. 허가, 사용 후 반환

. 어른스러운 혹은 자유에 대한 책임이 따르는 메모리 사용방법


* malloc()

. 자동 변수로 사용할 수 있는 메모리와는 비교할 수 없는 큰 메모리를 자유롭게 다룰 수 있음

. 동적(dynamic, runtime) 할당 가능

. 반환(또는 해제)의 책임이 따름


. void *malloc(size_t size);

. 인자 : size - 할당받을 메모리의 바이트 단위 크기

. 반환값 : heap 영역에 할당된 메모리 덩어리 중 첫번째 바이트 메모리의 주소

  에러가 발생하면 Null 반환

. 설명 : 할당받은 메모리는 반드시 free() 함수를 이용해서 반환해야 함.

           메모리를 초기화하려면 memset() 함수를 이용, 기본적으로는 쓰레기 값이 들어있음


. void free(void *memblock);

. 인자 : memblock - 반환할 메모리의 주소

. 반환값 : 없음

. 설명 : 동적으로 할당받은 메모리를 OS에 반환하는 함수


. ex)


#include <stdlib.h>

int main(void)
{
 int *pList = NULL;

 pList = malloc(sizeof(int) * 3);   //12bytes

 pList[0] = 10;
 pList[1] = 10;
 pList[2] = 10;


 free(pList);


 return 0;
}

----------------------------------------------

free(pList) 전까지의 메모리 상태를 보면,

0x0016FCA4  fd fd fd fd  ????                     // fd fd fd fd 사이 12bytes가 동적메모리 할당받은 영역
0x0016FCA8  0a 00 00 00  ....                     // pList 3개 요소가 10(0a)으로 됨을 볼 수 있다
0x0016FCAC  0a 00 00 00  ....
0x0016FCB0  0a 00 00 00  ....
0x0016FCB4  fd fd fd fd  ????                     // fd fd fd fd 사이 12bytes가 동적메모리 할당받은 영역



...


free(pList); 가 수행되서 반환하게 되면 메모리 상태는,

dd dd dd dd 로 초기화되네(visual studio 2017의 경우임)


0x0016FCA4  dd dd dd dd  ????
0x0016FCA8  dd dd dd dd  ????
0x0016FCAC  dd dd dd dd  ????
0x0016FCB0  dd dd dd dd  ????
0x0016FCB4  dd dd dd dd  ????


------------------------------------------------

pList[2] 라인 하단에 아래 행을 추가하고 실행하면,


 *(((char*)pList) + 12) = 'A';      //pList를 char(1byte)에 대한 포인터로 강제 형변환 후 +12 만큼 더하고
                                             // 그 주소 위치의 값을 'A'로 대입하면


malloc()를 통해 할당된 영역 12바이트 밖 13바이트째가 fd에서 A(41)로 하나 바뀌게됨.


0x011B554C  fd fd fd fd  ????
0x011B5550  0a 00 00 00  ....
0x011B5554  0a 00 00 00  ....
0x011B5558  0a 00 00 00  ....
0x011B555C  41 fd fd fd  A???


fd fd fd fd 사이 12bytes가 동적메모리 할당받은 영역이라고 했는데 변형되었음.

이후 다음줄인 free(pList)가 수행되면서, 프로그램에서 디버그 에러가 남. 

--> heap corruption detected. 힙 버퍼의 끝부분 메모리에 어플리케이션이 써버린 CRT가 검출되었다는 내용의 에러 


즉, fd fd fd fd 부분은 동적 할당한 메모리 영역을 표시하고, buffer overflow 또는 underflow를 탐지하기 위한 c의 수단이다.