빌더(TWx) 님이 쓰신 글 :
: 초보 님이 쓰신 글 :
: : 누가 배열로 얼마까지 버퍼를 잡아둘수 있나? 고 여쭤보셔서
: :
: : 사용환경은 XE8 입니다.
: :
: : #include <vcl.h>
: : #pragma hdrstop
: :
: : #include "Main.h"
: : //---------------------------------------------------------------------------
: : #pragma package(smart_init)
: : #pragma resource "*.dfm"
: : TForm3 *Form3;
: :
: : AnsiString Tmp[30000000];
: : //---------------------------------------------------------------------------
: : __fastcall TForm3::TForm3(TComponent* Owner)
: : : TForm(Owner)
: : {
: : }
: : //---------------------------------------------------------------------------
: :
: : 이렇게 하니 컴파일은 되는데
: :
: : tmp크기를 40000000 으로 잡으니 Link 에러가 나오고
: : 1억부터는 그냥 [ilink32 Error] Fatal: Out of memory 로 나오네요
: :
: : 이게 좀 재밌는게..
: : #define MAX 2100000000
: : AnsiString Tmp[MAX];
: :
: : 이렇게 하면 아무 문제 없이 컴파일이 되네요..
: : 1억으로도 안되던게 21억을집어넣으니깐 되는데 22억은 안되네요 .
: :
: : 왜 이런건지 설명해주실분 계실런지요?
: :
: : 물론 이렇게 배열 잡아서 코딩하는것도 나쁘지만 이런 배열을 써야 한다면 동적 메모리로 잡아야 하겠죠?;
: :
: :
:
:
: 답변:
:
:
: 컴파일러가 허용하는 정적배열의 최대치를 알아내려면 BYTE tmp[xxxx] 형태로 해야죠.
: C++빌더에서 AnsiString은 AnsiStringT<0> 로 인스턴스 되어지는 템플릿 클래스이고
: 문자셋 Encoding을 위한 클래스 내부 변수를 포함하기 때문 입니다.
:
: 그리고...
:
: #define 신텍스로 Numeric Constant 값을 정의할 때... 다음과 같은 식으로 명시적으로 정의하지 않으면
: 큰 수에 대해서 Numeric Overflow가 발생해서 값이 짤리게 됩니다.
:
: #define MAX 100000000UL // UL 로 명시적으로 지정해 주지 않으면 Numeric Overflow가 발생하면서 값이 짤림.
:
추가 의견 달아요.
컴퓨터에서 메모리 할당은 결국은 정적, 동적 할당 2가지 방법밖에 없습니다.
정적은 힙 또는 스택이 아닌 나머지 메모리에 할당되며, 컴파일단계에서 위치를 배정받습니다.
컴파일 단계에서 링커가 배정하는데 만약 용량이 넘으면 링커가 에러를 발생시킵니다
동적은 힙 또는 스택에 위치를 배정받는데 프로그램이 동작하면서 배정받습니다.
런타임에 배정된다라고 보시면 됩니다.
물론 컴파일이 된다고 하더라도 동작중에 프로그램이 죽을수 있습니다.
예로 uint8(unsigned char) 의 최대값이 256 이니까
255을 넣으면 255 % 256 = 255
256을 넣으면 256 % 256 = 0
257을 넣으면 257 % 256 = 1
처럼 짤리니 그렇게 된것이라 빌더(TWx)님 께서 설명해 주셨네요
#define MAX 100000000UL // UL 로 명시적으로 지정해 주지 않으면 Numeric Overflow가 발생하면서 값이 짤림.
위 내용은 알고는 있는 내용이었지만 따로 생각해 본적은 없었네요.
알고 있어도 고민해보지 않으면 정작 필요할떄 생각이 안 나는것 같아요.
좋은 기회였습니다.
감사합니다.
|