|
이긍... 생각좀 해 보시지..
자, 우선 _msize를 쓰시려면 Use dynamic RTL을 쓰시면 됩니다. MS의 CRT를 쓰는 경우기 때문에요.
다시 말씀드리지만, 이경우 exe화일을 배포할때 런타임라이브러리를 다 모아서 같이 배포해야 합니다.
빌더가 깔려있지 않은 시스템에 해당 실행화일을 던져주고 실행시키면, ~~.DLL이 없습니다. 하는
에러메시지를 실컷 받게 되죠.
그리고 제가 제시한 매크로 함수(msize) 를 사용하는 경우엔 그럴 필요가 없습니다.
어떤 라이브러리도 포함시킬 필요 없죠. 짧은 한 줄이지만 모든 기능이 구현되어 있으니까요.
malloc(100) 했다고 100 이 아닌 104 가 나온다든지
malloc(1)을 해도 12가 나온다든지 (맞나? 어쨌든 대충)
하는 문제는 memory align의 문제입니다.
기본적으로 할당된 메모리의 크기를 프로그램이 알기 위해 4바이트의 공간(32비트 시스템에서)을
할당된 크기를 적어 넣기 위해 사용중입니다.
즉 1바이트를 할당해도 1+4 바이트를 쓰게 되죠.
또한, CAS나 RAS, MMU 같은 컴퓨터아키텍트에서 설명하는 메모리 어드레싱 구조와 관리구조를 이해하신다면,
1바이트 단위의 주소지정이 느리다는걸 아실 수 있으실테고,
속도 성능을 위해 4바이트 단위라든지 2의 지수형태로 메모리를 정렬하는쪽이 빠르다는걸 아실겁니다.
사실, 1바이트 단위로 할당하는 경우는 잘 없기 때문에 API나 LIB함수에서 1바이트 단위 할당을 지원해준다면
어떤 초보가 열심히 1바이트 단위 할당 해제를 반복하다가 메모리가 조각나 사용할 용량이 남아나지
않는 경우도 생길 수 있습니다. (블럭단위의 경우 재사용가능성은 좀 더 늘어난다고 볼 수 있죠)
(모르신다면 컴퓨터 아키텍트를 공부하세요. 모른다고 질문 펑펑 날리면 저는 아무 일도 못합니다)
즉, 1바이트지만, 다음 메모리 할당이 되는 위치가 4바이트 형태로 간다면,
그 뒤 3바이트는 아무것도 안쓰도록 내버려 두게 됩니다.
따라서 기본적으로 1바이트라 하더라도 4바이트가 잡히게 되죠.
가령 malloc(11)을 했을땐 4의 배수 형태로 12바이트가 할당되고 1바이트는 그냥 놀게 되고,
사용량을 표기하기 위해 사용했던 4바이트가 추가되어 16바이트가 사용중이라고 나오는겁니다.
또한 OS나 컴파일러에서 할당가능 최소단위를 규정해 놓은 경우 그 룰을 따르게 됩니다.
1바이트를 할당했을때 총 8바이트를 사용하지 않고 12바이트를 사용하게 되는 경우도 그것 때문이지요.
물론 이 malloc 메카니즘이란게, 컴파일러 마다 조금씩 다릅니다.
도스시절엔 용량 표기를 위해 2바이트를 사용하고, 그 안의 숫자도 paragraph(16바이트)단위 였던
컴파일러도 있었고, 빌더의 경우 용량 마킹이 +2 되게 되어있습니다. (왜그런진 저도 모릅니다.
까짓것 그런건 다 만든 사람들의 약속이고, 컴파일러 마다 다르니 일일이 알려고 드는게 시간낭비라고
생각합니다. 어쨌든 필요하면 쓸 수 있도록 다양한 배경 지식을 갖는게 중요한거겠죠)
급한 불 끄셨으면 찬찬히 스스로 공부하시는 미덕을 보이시기 바랍니다.
이윤관 님이 쓰신 글 :
: Use dynamic RTL을 체크하니까 컴파일은 됩니다.
: 근데 실행하니까.
: char *a = malloc(100)하고 _msize(a)나 msize(a) 해보면 104가 나옵니다.
: 왜 할당한 크기와 다른지요?
: 그리고 항상 +4만큼의 값이 나온는것도 아니네요.
: 감사합니다.
: ////////////////
:
: 열씸! 님이 쓰신 글 :
: : 아 project\lib 인걸로 착각했군요.
: : 하지만 #pragma라고 한건 CG32.LIB를 추가하란 소리가 아니었습니다.
: :
: : [Linker Error] Unresolved external '___org__msize' referenced from C:\PROGRAM FILES\BORLAND\CBUILDER6\LIB\CG32.LIB|_msize
: : [링커 에러] c:\program files\borland\cbuilder6\lib\cg32.lib 에서 사용된 _msize 외부 함수가 있는디 링크할때 찾아봐도 실체가 없더랏.
: :
: : 이란 소리니 cg32.lib는 있는데 _msize에 필요한 라이브러리의 링크가 없단 소리잖아요? 당연히 이미 cg32.lib가 존재하고 그걸 링크하다 에러났는데 cg32.lib를 링크한다고 달라지는건 없겠지요.
: :
: : _msize는 MSC에서 지원하는 함수라 그다지 써 본적 없지만,
: : 프로젝트 옵션에서 Use dynamic RTL 을 체크하시면 링크엔 문제가 없으실것으로 보입니다.
: : 다만 해당 프로그램을 배포하실때 필요한 CRT들을 함께 배포하셔야 하는 문제가 있을껄로 보이네요.
: :
: : 굳이 빌더에서 _msize를 쓰셔야 하신다면,
: : 저라면
: : #define msize(m) (*((int*)m - 1) - 2) 라고 선언해서
: : _msize함수가 아닌 매크로로 적당히 처리해 버릴것 같네요. (속도도 빠르고 좋잖아~)
: : malloc 메카니즘은 할당된 메모리 앞에 할당된 용량이나 (플랫폼에 따라 패러그래프 단위 혹은 다른 블럭단위)의 용량을 기재하게 마련이니까요
: :
: : char *a = (char *)malloc(100);
: : #define msize(m) (*((int*)m - 1) - 2)
: : Caption = AnsiString(msize(a)) + ":" + _msize(a);
: : free(a);
: : 이런식으로 코딩해 보시면 매크로로 만든 msize와 마이크로소프트의 런타임라이브러리 함수인 _msize가 동일하게 동작하는걸 확인하실 수 있을겁니다.
: :
: : younkwan 님이 쓰신 글 :
: : : 콤포넌트로 만든건 아닌데요..
: : : 그냥 새 프로젝트 하나 만들어서 Form1에 버튼을 클리하면 동작하도록 해도 안되고
: : : 프로젝트의 WinMain()에서 해봐도 안됩니다.
: : : 그리고 #pragma comment(lib, "CG32.LIB") 추가해도 안되네요...ㅠㅠ
: : :
: : : 열씸! 님이 쓰신 글 :
: : : : 컴포넌트로 만드셨나보군요. CG32.LIB라는.
: : : : 컴포넌트는 하나의 LIB라, LIB라는건 하나의 실행화일과 달리 모든 구성요소를 포함시킬 강제가 없습니다.
: : : : 즉, 이경우 msize 함수를 사용하긴 했지만, 함수의 호출 내용만 들어 있을뿐 라이브러리가 포함되지 않아서
: : : : 발생하는 경우겠지요.
: : : : 두 가지 해결방법이 있습니다.
: : : : 하나는 실행화일을 만드는 프로젝트에도 msize함수를 한번 호출해서 라이브러리가 링크 되게 하는 방법
: : : : (#pragma comment(lib, "화일명") 로 직접 지정해 줘도 되겠지만)
: : : : 또 하나는
: : : : 컴포넌트 쪽에 #pragma package(smart_init) 넣거나 빼 보시기 바랍니다.
: : : : 어떤 구조로 작성하셨는지 몰라 그냥 대강 답변해 드립니다.
: : : :
: : : : younkwan 님이 쓰신 글 :
: : : : : malloc로 할당된 메모리의 크기를 구하려고 _msize함수를 사용했습니다.
: : : : : 근데 컴파일시 Linker error에러가 발생합니다.
: : : : : 원인이 뭔가요?
: : : : :
: : : : : [Linker Error] Unresolved external '___org__msize' referenced from C:\PROGRAM FILES\BORLAND\CBUILDER6\LIB\CG32.LIB|_msize
: : : : :
: : : : :
: : : : : void test ()
: : : : : {
: : : : : char *b;
: : : : :
: : : : : b = (char *)malloc(100);
: : : : : Caption = AnsiString().sprintf("size=%d", _msize(b));
: : : : : free(b);
: : : : : }
|