김시환 님이 쓰신 글 :
: 쮸리 님이 쓰신 글 :
: : 이번에 제가 c++ builder( 볼랜드) 소스를 VS에 옮기는 작업을 하는 중인데
: : 아직 제가 초보라서요...
: :
: : int ReadCount = 528;
: : short *buff = new short[ReadCount];
: : c++ builder => buff = 40
: : VS => buff = -12851
: : 같은 구문인데 buff의 데이터값이 다르게 나오는 이유를 묻고 싶습니다.
: : c++ builder 기준으로 맞추려면 어떻게 해야 하는 지도 묻고 싶습니다.
: : 부탁드립니다.
: :
:
: 결론적으로 말씀 드리면 맞출 수 없습니다.
: 맞출 수 없는 이유는 두 컴파일러간에 값을 동일하게 할수도 없을 뿐더러 할 필요도 없기 때문입니다.
:
: 초보라고 쓰신거 보니 질문의 의도가 잘못된 듯 합니다.
:
: 배열을 buff 라는 이름으로 동적생성 했고, 그 배열의 이름의 값이 틀리다고 질문하셨는데
: 배열의 이름은 buff[0] 의 주소값이 들어갑니다. 이 주소값은 배열을 동적생성 할때 마다 변할 수 있습니다.
:
: 물론 C 언어의 특성상 그 번지값을 임의의 번지로 할당할 수는 있겠지만 그렇게 했다가는 PC가 중간에 뻣어 버릴수도
: 있습니다.
:
: 다시한번 잘 훝어 보시고 질문의 요지가 뭔지 다시 생각해 보시고 질문을 다시 올리셔야 할 듯 합니다.
:
:
:
답변:
short* buf = new short[ReadCount];
new 로 할당된 버퍼의 메모리 내용이 컴파일러 마다 다른 것은...
디폴트 new 오퍼레이터는 메모리를 할당만 할 뿐...
할당된 메모리를 별도로 클리어하지 않기 때문 입니다. 클리어가 안되므로 버퍼에 들어가는 내용들은 쓰레기 값.
컴파일러에 따라서 디버깅 모드시 0 값으로 클리어되도록 new 런타임 코드가 오버로드 되어 사용되는 경우가
있긴 하지만...
할당되는 메모리 내용을 특정 값으로 클리어하도록 강제하지 않는 것은 퍼포먼스 때문 이죠.
필요할 때만 오버로드 해서 사용하라는 취지.
new 로 할당되는 메모리가 특정 값으로 클리어된 상태로 할당되도록 하려면
operator new[] 를 오버로드해서 따로 정의해 주면 됍니다.
void * operator new[](std::size_t n)
{
return calloc(1, n);
}
void Foo()
{
const int ReadCount = 528;
short* buf = new short[ReadCount];
.....
}
위와 같은 식으로 operator new[] 를 오버로드해서 정의해 주면...
new 로 할당되는 메모리가 0 값으로 초기화 됨.
calloc() 함수는 메모리를 할당하고 0 값으로 메모리 내용을 클리어 함.
C++에선 new, new[] 와 같은 것도 오퍼레이터로 취급되기 때문에
메모리 할당을 사용자가 자유롭게 오버로드해서 사용하는 게 가능.
legacy 컴파일러에선 위와 같은 식으로 operator new[] 를 오버로드해서 사용하면 되고...
컴파일러가 aggregate initialization을 지원하면 오버로드 사용하지 않고..
다음과 같은 신택스를 이용해서 간결하게 코딩 할 수도 있지요.
파스칼 언어로는 이런 것들이 불가능.
void Foo()
{
const int ReadCount = 528;
short *pBuf = new short[ReadCount]{};
...
}
aggregate initialization {} 로 인해 할당되는 메모리 내용이 0 값으로 클리어 됨.