Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ alignof 연산자 완벽 가이드: 메모리 정렬(Alignment) 이해하기

프로그래밍 언어에서 연산자(operator)는 컴파일러에게 특정 작업을 수행하도록 지시하는 특수 기호입니다. C++에는 다양한 연산자가 존재하는데, 그중 alignof는 메모리 정렬을 확인할 수 있는 강력한 도구입니다.

alignof 연산자란?

alignof 연산자는 주어진 데이터 타입에 적용되는 정렬(alignment) 값을 반환하는 C++ 연산자입니다. 반환되는 값은 바이트(byte) 단위이며, 해당 타입의 객체가 메모리에서 어떤 경계에 맞춰 저장되어야 하는지를 나타냅니다.

C++11부터 표준으로 도입된 이 연산자는 성능 최적화나 저수준 메모리 작업 시 매우 유용하게 활용됩니다.

문법(Syntax)

var align = alignof(type)

구성 요소 설명

  • alignof — 입력된 데이터 타입의 정렬 값을 반환하는 연산자입니다.

  • 매개변수 타입(parameter type) — 정렬 값을 확인하고자 하는 데이터 타입입니다.

  • 반환값(return value) — 해당 데이터 타입의 정렬로 사용되는 바이트 단위의 값입니다.

예제 1: 기본 데이터 타입의 정렬 값 확인

다음 프로그램은 C++의 기본 데이터 타입들이 가지는 정렬 값을 출력합니다.

#include <iostream>
using namespace std;
int main(){
    cout<<"Alignment of char: "<<alignof(char)<< endl;
    cout<<"Alignment of int: "<<alignof(int)<<endl;
    cout<<"Alignment of float: "<<alignof(float)<< endl;
    cout<<"Alignment of double: "<<alignof(double)<< endl;
    cout<<"Alignment of pointer: "<<alignof(int*)<< endl;
    return 0;
}

실행 결과

Alignment of char: 1
Alignment of int: 4
Alignment of float: 4
Alignment of double: 8
Alignment of pointer: 8

결과를 보면 char는 1바이트, int와 float는 4바이트, double과 포인터는 8바이트 단위로 정렬되는 것을 알 수 있습니다. 포인터가 8바이트로 표시되는 것은 64비트 시스템 환경에서의 실행 결과입니다.

예제 2: 배열, 구조체, 클래스의 정렬 값 확인

배열이나 사용자 정의 타입(구조체, 클래스)에도 alignof 연산자를 적용할 수 있습니다.

#include <iostream>
using namespace std;
struct basic {
    int i;
    float f;
    char s;
};
struct Empty {
};
int main(){
    cout<<"Alignment of character array of 10 elements: "<<alignof(char[10])<<endl;
    cout<<"Alignment of integer array of 10 elements: "<<alignof(int[10])<<endl;
    cout<<"Alignment of float array of 10 elements: "<<alignof(float[10])<<endl;
    cout<<"Alignment of class basic: "<<alignof(basic)<<endl;
    cout<<"Alignment of Empty class: "<<alignof(Empty)<<endl;
    return 0;
}

실행 결과

Alignment of character array of 10 elements: 1
Alignment of integer array of 10 elements: 4
Alignment of float array of 10 elements: 4
Alignment of class basic: 4
Alignment of Empty class: 1

흥미로운 점은 구조체 basic의 정렬 값이 4라는 것입니다. 이는 구조체 내부에서 가장 큰 정렬 요건을 가진 멤버(int, float = 4바이트)가 전체 구조체의 정렬을 결정하기 때문입니다. 또한 빈 클래스(Empty)의 정렬 값은 1로, 멤버가 없는 타입은 최소 정렬 단위를 갖습니다.

sizeof() 연산자와 alignof의 차이점

C++의 sizeof() 연산자는 피연산자가 차지하는 실제 크기(바이트 수)를 계산하는 단항 연산자입니다. 반면 alignof는 타입이 메모리에서 정렬되어야 하는 경계값을 반환합니다. 두 연산자는 서로 다른 정보를 제공하지만, 많은 경우 그 값이 일치하기도 합니다.

예제: sizeof와 alignof 비교

다음 프로그램은 sizeof 연산자와 alignof 연산자의 차이를 보여줍니다.

#include <iostream>
using namespace std;
int main(){
    cout<<"Alignment of char: "<<alignof(char)<<endl;
    cout<<"size of char: "<<sizeof(char)<<endl;
    cout<<"Alignment of pointer: "<<alignof(int*)<<endl;
    cout<<"size of pointer: "<<sizeof(int*)<<endl;
    cout<<"Alignment of float: "<<alignof(float)<<endl;
    cout<<"size of float: "<<sizeof(float)<<endl;
    return 0;
}

실행 결과

Alignment of char: 1
size of char: 1
Alignment of pointer: 8
size of pointer: 8
Alignment of float: 4
size of float: 4

기본 타입의 경우 크기(size)와 정렬(alignment) 값이 동일하게 나타나지만, 구조체처럼 여러 멤버로 구성된 타입에서는 패딩(padding)으로 인해 두 값이 달라질 수 있습니다. 따라서 메모리 레이아웃을 정확히 이해하려면 두 연산자를 함께 활용하는 것이 좋습니다.

마무리

alignof 연산자는 C++11에서 도입된 표준 기능으로, 타입의 메모리 정렬 요건을 손쉽게 확인할 수 있게 해줍니다. 특히 SIMD 연산, 네트워크 프로토콜 구현, 하드웨어 인터페이스 개발 등 정렬이 중요한 저수준 프로그래밍에서 필수적인 도구이니, 위 예제들을 직접 실행해 보며 익혀두시길 권장합니다.