`calloc` — 0으로 초기화된 메모리를 할당하는 함수
calloc — 0으로 초기화된 메모리를 할당하는 함수
malloc으로 할당하면 메모리 안에 어떤 값이 들어 있는지 모르죠. "배열을 잡았는데 처음엔 전부 0으로 시작하면 좋겠다" 같은 경우가 있는데, 그럴 때 쓰는 함수가 calloc이에요. 할당과 동시에 모든 바이트를 0으로 채워 줍니다.
본문
calloc은 크기가 size인 객체 num개만큼의 배열을 위한 메모리를 할당하고, 할당된 저장소의 모든 바이트를 0으로 초기화해요.
문법
#include <stdlib.h>
void *calloc( size_t num, size_t size );
설명
할당에 성공하면, 기본 정렬(fundamental alignment)을 가진 어떤 객체 타입에도 맞게 정렬된 메모리 블록의 가장 낮은(첫) 바이트를 가리키는 포인터를 돌려줘요. size가 0이면 동작은 구현에 정의됩니다(널 포인터가 돌아올 수도, 저장소에 접근하면 안 되는 널 아닌 포인터가 돌아올 수도 있어요).
calloc은 스레드 안전(thread-safe)해요. 인자를 통해 보이는 메모리 위치만 접근하는 것처럼 동작하죠. 한 영역의 메모리를 해제하는 이전의 free, free_sized, free_aligned_sized(C23부터), 또는 realloc 호출은, 같은 영역이나 그 일부를 할당하는 calloc 호출과 동기화됩니다.
매개변수
| 매개변수 | 설명 |
|---|---|
num |
객체의 개수 |
size |
각 객체의 크기 |
반환값
성공하면 새로 할당된 메모리의 시작을 가리키는 포인터를 돌려줘요. 메모리 누수를 막으려면 돌려받은 포인터를 free()나 realloc()로 해제해야 합니다. 실패하면 널 포인터를 돌려줍니다.
주의
정렬 요구 때문에, 실제로 할당된 바이트 수는 반드시 num * size와 같지는 않아요.
모든 비트가 0인 초기화가 부동소수점을 0.0으로, 포인터를 널 포인터 값으로 초기화한다는 보장은 없어요(흔한 플랫폼에서는 그렇지만요).
calloc의 0 크기 지원은 원래(C89에서) 이런 코드를 수용하기 위해 추가됐어요.
OBJ *p = calloc(0, sizeof(OBJ)); // "zero-length" placeholder
...
while (1)
{
p = realloc(p, c * sizeof(OBJ)); // reallocations until size settles
...
// code that may change c or break out of loop
}
예시
4개의 int 배열을 할당하고 전부 0으로 초기화해서 그대로 출력하는 예시예요. 같은 일을 하는 세 가지 표현을 함께 보여 줍니다.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *p1 = calloc(4, sizeof(int)); // allocate and zero out an array of 4 int
int *p2 = calloc(1, sizeof(int[4])); // same, naming the array type directly
int *p3 = calloc(4, sizeof *p3); // same, without repeating the type name
if (p2)
{
for (int n = 0; n < 4; ++n) // print the array
printf("p2[%d] == %d\n", n, p2[n]);
}
free(p3);
free(p2);
free(p1);
}
출력:
p2[0] == 0
p2[1] == 0
p2[2] == 0
p2[3] == 0
malloc과 달리 초기화 없이 바로 출력해도 전부 0이 나오는 걸 볼 수 있어요. 할당한 포인터는 전부 free로 해제해 준 점도 확인해 주세요.
더 알아보기
malloc— 메모리를 할당해요.realloc— 메모리 영역을 재할당해요.- cppreference의 calloc 원문에서 표준 항목별 세부 규칙을 더 확인할 수 있어요.