정의
•
서로 다른 DLL에서 동적 할당(new)과 해제(delete)가 이루어질 때 발생하는 문제
•
각 DLL이 독립적인 CRT(C Runtime Library) 힙을 사용하기 때문에 발생
원인
•
DLL마다 서로 다른 CRT 버전이나 런타임 라이브러리 옵션(/MD, /MT 등)을 사용하는 경우
•
각 DLL이 로드될 때 자신만의 CRT 힙을 생성하여 사용
•
DLL 간 메모리 할당/해제 정책의 격리, CRT 설정 차이, DLL 언로드 시 메모리 해제 등을 위해 독립적인 힙 생성
문제점
•
DLL A에서 할당한 메모리를 DLL B에서 해제하면 힙 충돌(heap corruption) 발생
•
메모리 누수, 프로그램 크래시 등 심각한 런타임 오류를 유발
해결 방안
•
DLL 경계를 넘나드는 동적 할당과 해제를 피함
•
동적 할당한 객체를 반드시 같은 DLL 내에서 해제
•
스마트 포인터(shared_ptr, unique_ptr)를 활용해 메모리 소유권을 명확히 함
◦
shared_ptr의 사용자 정의 삭제자를 통해 DLL 경계를 넘는 객체 공유 시 안전성 확보
예시 코드
// DLL A
class DLLA_API Widget {
public:
~Widget();
// ...
};
std::shared_ptr<Widget> createWidget() {
return std::shared_ptr<Widget>(new Widget(), [](Widget* p) {
delete p; // DLL A의 힙에서 메모리 해제
});
}
// DLL B
std::shared_ptr<Widget> widget = createWidget(); // DLL 경계를 넘어 객체 공유
C++
복사
추가 고려사항
•
C++11 이후 도입된 스마트 포인터를 적극 활용하여 교차 DLL 문제 완화
•
DLL 인터페이스 설계 시 동적 할당과 해제를 최소화하고, 값 타입이나 참조 타입 사용 고려
•
모듈화와 컴포넌트 기반 설계를 통해 DLL 간 의존성을 낮추는 것이 바람직함
정리
교차 DLL 문제는 C++ 개발자라면 반드시 이해하고 대처해야 하는 중요한 이슈입니다. 인터페이스 설계 시 이 문제를 고려하고, 스마트 포인터와 사용자 정의 삭제자를 활용하여 안전하고 효과적으로 DLL 간 객체를 공유할 수 있습니다. 또한 DLL 인터페이스 설계와 아키텍처 측면에서도 이 문제를 줄일 수 있는 방안을 모색해야 합니다.