동적으로 할당받은 메모리의 크기를 구하기
sizeof
함수는 (정확히는 매크로 함수) 타입의 크기를 반환한다. 배열 이름은 배열의 시작번지를 나타내므로 포인터와 거의 동일하게 취급되고, 또 많은 서적에서 이 둘을 같은 것이라고 말하는데, 사실은 다르다. sizeof()
함수는 배열을 인자로 넣으면 배열의 크기를 알려준다. 따라서 배열의 요소의 개수는 sizeof(intArr) / sizeof(int)
와 같은 식으로 구할 수 있다.
이와 반대로 동적으로 메모리를 할당받는 malloc 류의 함수는 포인터를 반환한다. 포인터는 unsigned long int
형으로 시스템에 따라 4혹은 8바이트의 크기가 된다. 따라서 배열을 동적으로 할당하기 위해 메모리 할당 함수를 사용하면 sizeof(포인터이름)
은 포인터의 크기를 반환하므로 배열의 요소의 개수를 알아낼 수가 없다.
사실 이미 메모리를 할당하는 시점에, 크기를 지정해 주었으므로 그 영역의 크기는 알고 있는 상황이지만 이 값을 변수에 담아서 계속 들고다니기란 조금 귀찮다. 여기서는 배열을 할당할 시에 그 크기를 나중에 알 수 있도록 하는 꼼수를 소개한다.
먼저 malloc 함수의 선언을 보면 void * malloc(size_t size)
로 되어 있다. 여기서 size_t
는 많은 경우에 unsigned long int
로 되어 있으므로, 메모리를 할당할 때 이 크기만큼 메모리를 더 할당해서 할당 영역의 처음에 길이 값을 저장해두고, 그 다음 번지를 리턴하는 함수를 만들면 된다.
다음에 소개하는 lalloc
함수는 이런 동작을 하고 있으며, 이 영역의 크기 값은 *(ptr - sizeof(size_t))
를 통해 알 수 있다.