atoi() 함수에 관해서 끄적끄적 질문

프로그래밍 일반에 관한 포럼입니다.

Moderator: 류광

Locked
비회원

atoi() 함수에 관해서 끄적끄적 질문

Post by 비회원 »

atoi() 함수가 리턴해주는 값이 DEBUG 모드일땐 정상적이지만 RELEASE 모드일땐 무조건 잘못된값을 리턴해주는 경우가 있습니다.

물론 불안정한 코드일때 발생하는 경우이지만

어째서 디버그 모드일땐 정상적인 값이 나오고 릴리즈 모드일때만 비정상적인 결과가 나오는 차이가 나는지가 궁금합니다.

각설하고 코드 조각으로 올려볼까요??

#include <stdio.h>
#include <assert.h>

int nTestInt = 102345;
char sztest[16];
sprintf(sztest, "%d", nTestInt);
int nLength = strlen(sztest);
int nResult;
for( int i = 0; i < nLength; i++)
{
char sztemp1;
CopyMemory( &sztemp1, &sztest, sizeof(sztemp1));
nResult = atoi( &sztemp1);
if( nResult < 0 || nResult > 5)
{
char sztempResult[48];
sprintf(sztempResult,"%d <-- 이런 이상한 숫자가 들어왔어요", nResult);
MessageBox( NULL, sztempResult, "난 메세지 박스", MB_OK );
}
}

물론 sztemp1 이라는 녀석에게 NULL 값이 들어갈 자리조차 주지 않은게 가장 근본적인 잘못이지만.

저 코드 직접 돌려볼 필요도 없겠지만... 어째서 DEBUG 모드일땐 되고 RELREASE 모드 일땐

안되는 차이가 나는건지 살짝콩 궁금해져서 이렇게 질문 올립니다..
비회원

Post by 비회원 »

잘못된 코드를 최적화 할때 더 이상한 문제가 생길수 있죠
비회원

Post by 비회원 »

애초부터 디버그 버전 런타임 라이버러리랑 릴리즈 버전 런타임 라이버러리는 코드 자체가 틀리니까요.

서로 다른 코드에서, 함수 스팩외 부분에서 다른게 동작하는건 자연스러운거라고 봐야겠죠.
ducklmg
Posts: 155
Joined: 2004-11-08 16:46

Post by ducklmg »

버그 때문에 둘 다 제대로 작동 안 되어야 정상이겠지만,

디버그 버전일 경우에는 값이 유효한지 검사도 하고,

비워지는 스택은 깨끗하게 0으로 청소도 하고,

힙을 할당할 경우에는 앞뒤로 몇바이트씩 더 붙여서 0xcd나 0xcc 같은 값으로 채워두기도 합니다.

이런 작동 때문에 가끔씩 돌아가서는 안되는 코드가 제대로 작동되는

어처구니 없는 일이 벌어지는 거죠...
난 너를 만나기 위해 이 세상에 태어났어
그러니 내 생활비는 네가 대 주어야만 해
moofasa
Posts: 158
Joined: 2004-08-02 11:02
Location: 모은행

Post by moofasa »

디버그 환경에서 옵티마이즈 옵션을 Maximize Speed 로 바꿔주시고
메모리 공간을 보시면서 디버깅 해보세요. (6.0 기준으로 alt+6)
그 변수 주위의 메모리 영역에 채워진 값이 다를 겁니다.
dingpong
Posts: 142
Joined: 2006-01-31 18:34
Location: (주)NHN
Contact:

Post by dingpong »

저도 atoi 때문에 고생한적이 있습니다.
그래서 저런식으로 쓰지 않고 sztemp1 라는 문자열이 있다면
char abc = sztemp1;
int(abc)-48 로 뽑아서 썻습니다^^;

참고 - 출처 : devpia
Debug 모드일 경우에는 왠만하면 메모리를 초기화 시켜버립니다. (NULL Pointer을 쉽게 디텍트하기 하려고 그렇습니다. 또는 0xcb로 채우기도 하죠...)
Release모드에서는 최적화 때문에 초기화를 하지 않으므로 변수 뒤에 \0 이 없어서 에러가 난겁니다.
theuhm
Posts: 32
Joined: 2006-01-31 13:51

Post by theuhm »

VC++의 디버그 빌드는 배열 선언시 padding 바이트를 두고 할당합니다.
이 padding 바이트 덕분에 배열 범위를 벗어나도 정상작동하는 것처럼 보입니다.
당연히 릴리즈 빌드에서는 padding 바이트가 제거되므로 숨겨져 있던 런타임 오류가 드러납니다.
Locked