C++ encoding 메모리 이슈

Gunjoo Ahn·2022년 9월 4일
0

회고

목록 보기
9/11
post-custom-banner

iconv.h

C++ 프로젝트를 진행하던중 기존 string들을 utf-8로 모두 다루던 것을 이제 다양한 charset을 지원하여야 했다. 따라서 iconv 헤더파일을 이용하여 encoding class를 만들어 encoding 구현을 완료하였다.

메모리 leak

그런데 갑자기 메모리 leak나서 보니, encoding output (char *)malloc을 해주고 나서 avro 객체에 output 주소값을 넘기는데, avro 객체가 죽으면서 encoding output을 따로 free를 해주지 않는 것이었다. 이유는 당연히 const string& 타입으로 받아 자신은 free를 하지 않아도 된다고 판단하는 것이다. 그러면 따로 해당 주소값을 사용이 완료된 이후에 free를 해주어야 하는데, avro가 네트워크 통신을 완료된 시점에 해야하는데 당연히 구현 난이도가 올라간다.

따라서 큰 고민없이 그냥 스마트 포인터를 쓰려고 했다. 하지만 문제는 스마트 포인터를 avro가 생성한 set_string함수에서 인풋으로 가져가지 않는다는 점이다. 그렇다고 move를 통해 주소를 안넘겨주자니 avro가 네트워크 통신을 하기전에 스마트 포인터가 죽으면서 output이 free가 되버릴 가능성이 있었다.

해결은 간단,,

생각해보니 그냥 string으로 넘기면 됐다. encoding할때만 잠깐 malloc을 하고 새로운 stack 공간에 선언한 string으로 복사하고 기존 mallocfree해버리면 해결되는 것이었다. 이것이 해결되는 이유는 string이 스택공간에 있어서 계속 값복사를 통해서 string을 전달하기 때문이다.

Encoding할 때 malloc을 한 이유

최대 길이(64kb)까지 Input string 길이가 가변이기 때문이다. 그리고 encoding으로 인하여 글자당 byte가 변할 수 있다. 따라서 input string 길이에 항상 2배의 output 메모리 공간을 할당받아 encoding을 하였다.

Reference

로컬 변수(stack 영역)로 선언한 std::string이 함수 종료와 함께 free된다는 이야기
https://stackoverflow.com/questions/4979681/how-to-properly-free-a-stdstring-from-memory

profile
Backend Developer
post-custom-banner

0개의 댓글