`aligned_alloc` — 정렬을 지정해 메모리를 할당하는 함수
aligned_alloc — 정렬을 지정해 메모리를 할당하는 함수 (C11)
malloc이 돌려주는 메모리는 어떤 객체든 담을 수 있게 기본 정렬(fundamental alignment)로 맞춰져 있어요. 그런데 캐시라인이나 SSE, VM 페이지 경계처럼 더 엄격한 정렬이 필요한 경우도 있죠. 그럴 때 정렬 크기를 직접 지정해 할당하는 게 aligned_alloc이에요.
본문
aligned_alloc은 alignment로 지정된 정렬을 갖는, 초기화되지 않은 저장소를 size 바이트만큼 할당해요.
문법
#include <stdlib.h>
void *aligned_alloc( size_t alignment, size_t size ); // (C11부터)
설명
size 매개변수는 반드시 alignment의 정수 배여야 해요.
aligned_alloc은 스레드 안전(thread-safe)해요. 마치 인자를 통해 보이는 메모리 위치만 접근하고 정적 저장소에는 접근하지 않는 것처럼 동작하죠. 한 영역의 메모리를 해제하는 이전의 free, free_sized, free_aligned_sized(C23부터), 또는 realloc 호출은, 같은 영역이나 그 일부를 할당하는 aligned_alloc 호출과 동기화(synchronizes-with)됩니다.
매개변수
| 매개변수 | 설명 |
|---|---|
alignment |
정렬을 지정해요. 구현이 지원하는 유효한 정렬이어야 합니다. |
size |
할당할 바이트 수. alignment의 정수 배여야 해요. |
반환값
성공하면 새로 할당된 메모리의 시작을 가리키는 포인터를 돌려줘요. 메모리 누수를 막으려면 돌려받은 포인터를 free나 realloc로 해제해야 합니다. 실패하면 널 포인터를 돌려줍니다.
주의
size가 alignment의 정수 배가 아니거나, alignment가 유효하지 않거나 구현이 지원하지 않는 값이면 함수는 실패하고 널 포인터를 돌려줘요. (C11이 처음 발표됐을 때는 이 경우 동작이 정의되지 않는다고 되어 있었는데, DR460으로 시정됐습니다.) 제한적인 정렬 경계에 작은 객체를 할당할 수 있게 크기 제한을 없애자는 제안(N2072)도 있었어요.
"구현이 지원하는 정렬"이 무슨 뜻인지 예를 들어볼게요. POSIX의 posix_memalign은 2의 거듭제곱이면서 sizeof(void *)의 배수인 정렬을 받아들이는데, POSIX 기반의 aligned_alloc 구현도 이 요구를 그대로 물려받아요.
기본 정렬은 항상 지원됩니다. alignment가 2의 거듭제곱이고 _Alignof(max_align_t)보다 크지 않다면, aligned_alloc은 그냥 malloc을 호출할 수도 있어요.
여기서 malloc과의 차이를 한 번 더 짚어볼게요. 일반 malloc은 기본 정렬을 가진 어떤 객체 타입에도 맞는 메모리를 정렬하지만, aligned_alloc은 SSE, 캐시라인, VM 페이지 경계 같은 과정렬(over-aligned) 할당에 유용합니다.
이 함수는 Microsoft C 런타임 라이브러리에서는 지원되지 않아요. MS의 free 구현이 어떤 정렬 할당도 다룰 수 없기 때문이에요. 대신 MS CRT는 _aligned_malloc(해제는 _aligned_free로)을 제공합니다.
예시
기본 정렬된 malloc 주소와 1024바이트 정렬된 aligned_alloc 주소를 비교하는 예시예요.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *p1 = malloc(10 * sizeof *p1);
printf("default-aligned addr: %p\n", (void*)p1);
free(p1);
int *p2 = aligned_alloc(1024, 1024 * sizeof *p2);
printf("1024-byte aligned addr: %p\n", (void*)p2);
free(p2);
}
가능한 출력:
default-aligned addr: 0x1e40c20
1024-byte aligned addr: 0x1e41000
aligned_alloc(1024, ...)으로 할당한 주소 0x1e41000은 1024(=0x400)로 나누어떨어지는, 즉 1024바이트 경계에 정렬된 주소라는 걸 확인할 수 있어요.
더 알아보기
malloc— 메모리를 할당해요.free_aligned_sized— 정렬되고 크기가 지정된 메모리를 해제해요 (C23).- cppreference의 aligned_alloc 원문에서 표준 항목별 세부 규칙을 더 확인할 수 있어요.