Post

C++ Dynamic Size Buffer Without Initialization And Memory Leak

오랫만에 C++ 관련 글링크 하나를 보게 되었는데, 조금 오류가 있길래 정확한 정보를 공유하고자 글을 한번 쓴다

목적은 간단하다

아래 코드의 dynamic 버전을 만드는 것. 즉 아무런 Overhead 없고, Memory Leak 에 대하여 안전한 Dynamic Buffer 를 만드는 것이다

1
2
3
4
void foo() {
   auto arr = char[100];
   // todo: blabla
}   

예제를 하나씩 만들어 보자

1
char[] arr = new char[size];

위 코드는 arr 의 해제가 수동이라, Memory Leak 에 대하여 자유롭지 않다

1
std::shared_ptr<char> arr(new char[size], [](const char* p) { delete [] p; } );

이 코드는 memory 할당이 2번(new char[] 에 한번, reference count 변수 할당에 한번) 일어나고, 레퍼런스 카운팅을 추가로 진행하여, 성능에 패널티가 있다 사실 저렇게 할 필요 없이 아래 코드면 충분 하긴 했다.

1
std::shared_ptr<char[]> arr(new char[size]);
1
std::shared_ptr<char[]> arr = make_shared<char[]>(size);

위 코드는 memory 할당은 한번으로 줄어들지만, 레퍼런스 카운팅 자체는 진행되므로 오버헤드가 있다

1
std::vector<char> arr(size);

위 코드는 arr 의 모든 요소에 대해 zero fill 이 일어나서 성능에 패널티가 있다

1
std::unique_ptr<char[]> arr = std::make_unique<char[]>(size);

원본 글에서는 위 방법을 추천 하고 있지만, make_unique 는 사실 vector 와 마찬가지로 zero fill 이 일어나서, 역시 성능상 패널티가 있다

1
std::unique_ptr<char[]> arr = std::unique_ptr<char[]>(new char[size]);

코드 자체로는 문제가 없다. 즉 C++ 17 까지로는 이것이 최선의 코드다. 단지 다른곳에서 생성 된 memory 를 넣을 수 있다는 특성상 중복해제의 위험성이 있을 수 있다.

C++ 20 에서는 이런 경우 사용하는 함수가 추가되었다

1
std::unique_ptr<char[]> arr = std::make_unique_for_overwrite<char[]>(size);

C++ 20을 지원하는 환경에 있다면 최고의 성능이 필요 할 경우 make_unique_for_overwrite 를 사용 하도록 하자

This post is licensed under CC BY 4.0 by the author.