Debug Assertion Failed! acrt_first_block == header

coldew·2022년 4월 19일
0

Debug

목록 보기
1/1

"Debug Assertion Failed! Expression: __acrt_first_block == header"

런타임 라이브러리 - 위키백과, 우리 모두의 백과사전

DLL이란?

가상 주소 공간 - 위키백과, 우리 모두의 백과사전

Windows

VC++ 빌드 옵션으로 MT, MD가 있다.
MT는 VC++런타임 라이브러리(lib)를 정적링크해서 프로그램을 빌드한다.
MD는 VC++런타임 라이브러리(dll)를 동적링크해서 프로그램을 빌드한다.
MT는 런타임 라이브러리가 프로그램에 포함되고 MD는 포함되지않는다.

런타임 라이브러리를 정적링크(MT) 해서 사용하는경우

라이브러리L을 불러오는 프로세스A가 라이브러리에서 정의한 객체를 생성하고 삭제할때 "Debug Assertion Failed! Expression: __acrt_first_block == header" 에러를 볼 수 있다. 참고 라이브러리L내부에서 할당한 힙 메모리를 프로세스A가 해제하려고 할때 생기는문제인데
프로세스A와 라이브러리L의 힙공간이 다르면 발생한다. 프로세스A가 삭제하려는 주소와 라이브러리가 생성한 주소가 서로 다른곳을 가리키기 때문.

왜 힙공간이 서로다른가

메모리를 할당해주는 new나 malloc은 런타임 라이브러리에 있는데
A와 L은 런타임 라이브러리를 각자 정적링크해서 빌드하여 사용하기 때문에 힙영역도 따로따로 가지고있다.
꼭 MT로 빌드해서 사용해야한다면 라이브러리 내부에 생성, 삭제해주는 함수를 만들어서 라이브러리가 직접 생성, 삭제 해주도록 역할을 넘겨주면 해결된다.

런타임 라이브러리를 동적링크(MD)로 사용해도 괜찮다면 문제는 해결된다. 하지만 MD로 사용하면 프로그램 배포시 런타임 라이브러리도 함께 배포해야한다.

런타임 라이브러리를 동적링크(MD)하면 문제가 해결되는 이유

dll은 런타임에 메모리가 올라간다고 알고있을것이다.
프로세스가 dll을 사용할때 dll의 메모리가 물리 메모리에 올라가고 프로세스의 가상주소공간에 매핑이 되는 방식이다.

그리고 만약 프로세스A가 dll을 사용하는중에 또 다른 프로세스B가 같은 dll을 사용하려 한다면 이미 물리 메모리에 올라와있는 dll의 메모리공간에 B의 가상 주소공간이 매핑된다.
결국 A와 B가 사용하는 dll의 메모리 공간은 같은 공간이다.

이런이유로 런타임 라이브러리를 동적링크하면 라이브러리L에서 사용하는 힙공간은 프로세스A의 힙공간과 같은 공간이기 때문에 생성, 삭제에 문제가 없다.

0개의 댓글