/ C, PROGRAMMING, DATASTRUCTURE

C언어: Dynamic Storage Allocation

문자열을 다룰 때 유용하다.

malloc()

argument는 바이트 단위로, 동적으로 메모리를 할당할 크기에 해당한다. 리턴값은 void*형이다. 사용 목적에 따라 사용하고자 하는 포인터형으로 캐스팅 가능하다. (근데 필수는 아니고 어차피 자동 형변환 일어남)

(주의: 배열과 비슷하게 초기화와 동시에, 포인터 상수에만 할당하자.)

  • 문자열 할당 시

    • char*형 포인터에 malloc(문자열 길이+1(널문자 포함)) 으로 할당한다.

    • 이후 strcpy() 등으로 초기화 가능하다.

공간 할당 실패 시, 널 포인터 (NULL) 을 반환한다. 이 함수를 사용 시 반드시 반환된 포인터가 NULL이 아닌지 검사할 필요가 있다.

free(void*)

  • malloc() 등으로 할당된 동적 메모리를 free 한다.

  • free 직후 해당 영역을 가리키는 포인터는 dangling pointer가 된다. 이 포인터에 다시 접근하면 UAF가 발생하므로, 바로 업데이트해 주어야 한다.

calloc()

void* calloc(size_t nmemb, size_t size);

element 수가 nmemb 이며 각 element의 크기가 size 인 배열을 동적으로 할당하고, 해당 메모리 블록의 모든 비트를 0으로 초기화한다.

구조체의 초기화에 이용 가능하다. nmemb 에 1을 대입하고 size에는 sizeof(구조체) 대입하면 모든 멤버가 0으로 초기화된 구조체가 할당된다.

realloc()

void* realloc(void* ptr, size_t size);

malloc(), calloc(), realloc() 으로 할당된 메모리의 크기를 재조정한다.

  • 메모리 블럭의 크기 확장 시, 블럭의 확장된 바이트는 초기화되지 않는다.

  • 크기 확장이 불가능한 경우에는 널 포인터가 반환된다.

  • 첫 번째 argument에 널 포인터를 전달하면 malloc()과 같이 동작한다.

  • 두 번째 argument에 0을 전달하면 메모리 블록을 free한다.

기본적으로는 메모리 블럭의 위치가 바뀌지 않으나, 현재 위치에서 확장이 어려운 경우 새로운 위치에 메모리를 할당하고 원래 있던 메모리 블럭의 값을 복사한다. 이런 경우에 대비하기 위해서 대상 메모리 블럭을 가리키던 모든 포인터들을 update해 주어야 한다.