블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2794)
Unity3D (852)
Programming (478)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (185)
협업 (11)
3DS Max (3)
Game (12)
Utility (68)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (55)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday
링크 : http://forums.andromedarabbit.net/wiki/%EC%9C%88%EB%8F%84%EC%9A%B0_%EC%95%88%EC%A0%84%ED%95%9C_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D

런타임 검사

[편집]개요

런타임 검사는 Runtime Check, RTC라고 한다. Visual Studio 2008을 기준으로 보면 [프로젝트 - 속성 - 구성 속성 - C/C++ - 코드 생성] 메뉴에 관련 옵션이 있다. 작은 형식 검사 (/RTCc), 기본 런타임 검사 (/RTC1, /RTCsu)가 런타임 검사에 속한다.

  • /RTCc

더 큰 데이터 형식의 값을 더 작은 데이터 형식에 할당할 때 데이터 손실이 발생할 수 있음을 결고한다. 예를 들어 INT64 변수 값을 INT32 변수에 할당하는 경우가 이에 해당한다. 물론 이러한 할당이 의도적이고 정확한 연산일 수도 있기 때문에 아무 때나 오류 메시지를 내보내진 않는다. 값 할당 시에 비트 연산자를 명시적으로 사용하면 RTCc 검사에 걸리지 않는다.

#include <crtdbg.h>
 
char get8bits(int value, int position) {
   _ASSERT(position < 32);
   return (char)(value >> position);
   // Try the following line instead:
   // return (char)((value >> position) && 0xff);
}
 
int main() {
   get8bits(12341235,3);
}
  • /RTCs

스택 프레임 런타임 오류 검사를 수행한다. MSDN 라이브러리 문서를 읽고 어떤 식으로 문제를 탐지해내는지 알아두면 커스텀 스택 메모리 할당자를 개발할 때 도움이 된다. Earlgrey 프로젝트의 StackAllocator는 이러한 사례 중 하나이다.

  • /RTCu

초기화되지 않은 변수가 사용될 때 보고한다.

  • /RTC1, /RTCsu

/RTC1은 /RTCsu를 뜻한다.


[편집]언제 쓰는가?

/RTC 옵션은 컴파일러가 탐지 기능을 삽입해 넣으므로 성능에 영향을 미친다. 더군다나 /RTC 옵션이 설정되면 최적화(optimize pragma, /O)도 되지 않는다. 그러므로 DEBUG 빌드 때에만 /RTC 옵션을 켜는 게 좋다.

[편집]boost::numeric_cast 와 /RTCc

/RTCc 옵션을 켠 상태로 boost::numeric_cast를 쓰다 보면 런타임 오류 메시지를 마주치게 된다.

TEST(EarlgreyMathTest, UIntToInt64)
{
	EARLGREY_STATIC_ASSERT(UINT_MAX < _I64_MAX);
 
	UINT src = 123;
	INT64 dst = EARLGREY_NUMERIC_CAST<INT64>(src);
	ASSERT_EQ(123, dst);
}

boost::numeric_cast 내부에서 비트 연산을 명시적으로 써서 컴파일러가 올바른 타입 변환임을 알게 해주었더라면 이런 문제가 없었을 것이다. 이 문제를 해결하려면 크게 두 가지 방법이 동원 가능하다.

  • boost::numeric_cast의 소스 코드를 고친다. 물론 써드파티 라이브러리를 손 대기 시작하면 이후에 최신 버전으로 업그레이드할 때 골이 아프다.
  • #pragma runtime_checks 지시자를 활용한다. 이 지시자를 사용하면 일부 함수에 한해 특정 런타임 검사를 무효화할 수 있다. 일반적으로 이 지시자로 문제 해결이 가능하지만 안타깝게도 boost::numeric_cast처럼 템플릿 함수일 때는 그렇게 상황이 단순하지 않다. 다양한 이슈가 있기 때문에 뒤에서 따로 이 문제를 다룬다. 여기선 /RTCc 옵션틀 끄는 편이 나을 수도 있다는 것만 언급한다.

[편집]/RTCc 와 #pragme runtime_checks

 
반응형
Posted by blueasa
, |


종종 프로젝트 설정을 잘 못 만지면 pre compiled header 에 대한 오류를 볼 수 있습니다. (나만 그런가?)
그냥 pre compiled header 를 사용안함으로 해버리면 해결 됩니다.

그러나 이건 근본적인 해결책은 되지 못하겠지요. 또한 pre compiled header 를 사용하는 이점을 모두 버려야 하구요 :-)


pre compiled header 옵션이 몇가지가 있는데 모두 어떻게 동작하는지 정확히는 알지 못하겠습니다. 
아무튼 난 기본 설정(미리 컴파일된 헤더 파일 사용)을 쓰고 싶단 말입니다 !!

자 ~ 원래 기본 설정(/Yu) 로 바꿔두고요..빌드를 해봅시다. 
당연히 미리 컴파일된 헤더를 찾을수 없다고 떠들어 대는 컴파일러 메세지를 볼 수 있을것입니다.


이는 "미리 컴파일된 헤더" 로 지정된 stdafx.h 때문에 그렇습니다. 
stdafx.cpp통해서 pch 파일을 생성하고, 나머지는 모두 만들어진 pch 를 통해서 컴파일이 됩니다. 
어디선가 pch 파일을 무턱대고 복사해놓고, 빌드를 하면 일치하지 않는다는 등의 또 다른 컴파일러의 불만을 보게 되겠지요. 


stdafx.cpp 의 속성을 위와 같이 미리 컴파일된 헤더 생성(/Yc) 로 두면 문제는 해결됩니다. 

stdafx.cpp 를 통해서 pch 를 만들고, 나머지 파일들은 pch 를 이용, 즉 설정 이름처럼 미리 컴파일된 헤더 사용이니까요. 결국 stdafx.cpp 는 미리 컴파일된 헤더를 만들어야 겠죠.. 

종종..이 문제때문에 프로젝트를 새로 생성했던 기억이 있어서.. 좀 뒤적거리다가 알아냈습니다. 


출처 :  
http://somma.egloos.com/2723641
반응형
Posted by blueasa
, |



참고 : 
http://cafe.naver.com/jzsdn/310  : 형변환 (float -> int)
http://cafe.naver.com/jzsdn/8571 : Fast sqrt 테스트..
http://cafe.naver.com/jzsdn/11236 : Intel FPU Rounding mode
 
 
참고내용을 토대로 정리를 조금 해보았습니다.
 
우선 형변환(float -> int)부터 적어 봅니다. 우선 결과입니다.

 

 

방법1) FPU를 이용한 인라인 어셈코드입니다.

 

int fastf2i_round(float f)
{
#ifdef _WIN32
 int i;
 __asm
 {
  fld  f
  fistp i
 }
 return i;
#else
 return (int)(f + 0.5f);
#endif 
}

 

장점 : 가장 빠릅니다.

단점 : 반올림이 됩니다. 따라서 int a = int(1234.56f) 와 같은 값이 안 나온다는 것입니다. 반올림되어서 1235가 나옵니다.

 

방법2) 역시 FPU를 이용한 인라인 어셈코드이지만 반올림을 안하도록 약간의 조정을 합니다.

 

int fastf2i(float fValue)
{
#ifdef _WIN32
 static const float round_to_nearest = -0.499999f;

    int iValue;
    __asm 
 {
  fld  fValue
  fadd round_to_nearest
  fistp iValue
 }
    return iValue;
#else
    return (int)fValue;
#endif
}


장점 : 역시 방법1과 흡사하게 빠릅니다.

단점 : 방법1에서 반올림이 안되도록 반올림값을 빼주고 있습니다만 0.9999999f식의 값이 들어오면 역시 반올림됩니다. 물론 round_to_nearest 를 약간 상황에 맞게 수정하면 되는 것입니다만 약간 찝찝한 것 사실입니다.

 

 

방법3) int변환을 그대로 인라인 어셈화 하였습니다.

 

int Float2Int( float a )
{
#ifdef _WIN32
 int CtrlwdHolder;
 int CtrlwdSetter;
 int RetVal;
 __asm 
 {
  fld    a     // push 'a' onto the FP stack
  fnstcw CtrlwdHolder   // store FPU control word
  movzx  eax, CtrlwdHolder // move and zero extend word into eax
  and    eax, 0xFFFFF3FF  // set all bits except rounding bits to 1
  or     eax, 0x00000C00  // set rounding mode bits to round down
  mov    CtrlwdSetter, eax // Prepare to set the rounding mode -- prepare to enter plaid!
  fldcw  CtrlwdSetter   // Entering plaid!
  fistp  RetVal    // Store and converted (to int) result
  fldcw  CtrlwdHolder   // Restore control word
 }
 return RetVal;
#else
 return (int)a;
#endif 
}

 

장점 : 일반 int형변환과 정확히 일치합니다.

단점 : 그다지 많이 빠르지 않네요.

 

방법4) Game Programming Gems2 chapter 2.1에 Yossarian King씨가 작성한 방법입니다.

 

typedef union
{
    int     i;          // as integer
    float   f;          // as float
    struct              // as bit fields
    {
        unsigned int    sign:1;
        unsigned int    biasedexponent:8;
        unsigned int    significand;
    } bits;
} INTORFLOAT;


INTORFLOAT  FTOIBIAS = {((23 - 0 + 127) << 23) + (1 << 22)};

 

int f2i(float f) 
{
 INTORFLOAT ftmp;
 ftmp.f = f;
 ftmp.f += FTOIBIAS.f;
 ftmp.i -= FTOIBIAS.i;
 return ftmp.i; 
}

 

장점 : FPU모드에 따라 일반적으로 일반 int형변환과 정확히 일치합니다.

단점 : float의 값이 2의 23승(8388608)보다 작아야 합니다. 또한, FPU모드가 Chopping이 아닌 경우. 예를 들면 위의 fastf2i_round나 fastf2i와 같이 사용하면 안됩니다. fastf2i_round나 fastf2i는 FPU모드를 반올림모드로 사용하는데, f2i함수는 FPU모드를 따로 설정하지 않기 때문에 현재 FPU모드 그대로 변환을 시도합니다. (FPU모드는 위의 참고를 보시기 바랍니다)

 

결론) 복잡하시죠? ^^

반올림이 상관없을 때는 fastf2i_round를 사용하세요.

일반 int형변환과 같이 같은 값이 나오기를 바라신다면 fastf2i나 Float2Int를 사용하세요.


출처 :  http://cafe.naver.com/jzsdn/11238

반응형
Posted by blueasa
, |

안녕하세요. 파코즌 원정상입니다.

금일 회사에 불법소프트웨어 단속이 들이 닥쳤습니다. ㅠㅠ

본의 아니게 사용하고 있는 불법 소프트웨어가 있을수도 있고, 자의에 의해서 사용하는 프로그램도 있을수 있습니다.

가끔 라이선스를 교묘하게 해놔, 기업의 개인사용자(?)들이 알게 모르게 불법을 사용하게끔 조장하는일이 있어(타의든 자의든) 오늘 이렇게 정리해 보았습니다.

(이 사이트에도 무료 프로그램 정리된것이 많은데, 개인과 기업 사용자들의 구분이 쉽지가 않아, 이렇게 기업용도 가능한 소프트웨어만 따로 모아봤습니다.)

아래 프로그램들은

개인뿐 아니라 기업에서까지 무료로 사용이 가능합니다.


오피스 프로그램

오픈오피스 : http://www.openoffice.org/

홈페이지 내용발췌 : OpenOffice.org uses the LGPL (GNU Lesser General Public License). For documentation and website content not intended to be included in the product, we use the Public Documentation License (PDL). Our License page provides more information on our licenses and on our policies regarding the application of those licenses. As well, our we have several FAQs dealing with licensing.

Telnet 프로그램


테라텀 : http://ttssh2.sourceforge.jp/

홈페이지 내용발췌 : TeraTerm Project would have been developed terminal emulator "Tera Term" and SSH module "TTSSH".

This software is open source software under BSD License.

PuTTY: http://www.chiark.greenend.org.uk/~sgtatham/putty/

홈페이지 내용발췌 : The PuTTY executables and source code are distributed under the MIT licence, which is similar in effect to the BSD licence.
 

압축 프로그램

빵집 : http://www.bkyang.com/

홈페이지 내용발췌 : 빵집은 개인, 기업, 학교, 피씨방, 관공서등 누구나 무료로 사용하실 수 있습니다.

7-zip : http://www.7-zip.org/

홈페이지 내용발췌 : 7-Zip is open source software. Most of the source code is under the GNU LGPL license.

밤톨이 : http://www.bamtory.com/new/main/main.asp
홈페이지 내용발췌 : 본 프로그램은 프리웨어로 개인/가정/사무/ 기업/관공서 등 어느곳에서나 아무런 제약없이 사용이 가능합니다.

다집 : http://datools.kr/

홈페이지 내용발췌 : 다씨(DaSee), 다집(DaZip), 다FTP(DaFTP)는 언제, 어디서, 누구나 기업체/관공서 상관없이 모든 사람이 무료로 사용할 수 있는 프리웨어입니다.
 

FTP 프로그램

파일질라 : http://filezilla-project.org/

오픈소스 진영에서 만들고 있는 강력하고, 빠르고, 좋은 프로그램~

다FTP : http://datools.kr/

홈페이지 내용발췌 : 다씨(DaSee), 다집(DaZip), 다FTP(DaFTP)는 언제, 어디서, 누구나 기업체/관공서 상관없이 모든 사람이 무료로 사용할 수 있는 프리웨어입니다.
 

에디트 프로그램

Notepad++ : http://notepad-plus.sourceforge.net/uk/site.htm
홈페이지 내용발췌 : Notepad++ is a free (as in "free speech" and also as in "free beer") source code editor and Notepad replacement that supports several languages. Running in the MS Windows environment, its use is governed by GPL License.

ACROEDIT : http://www.acrosoft.pe.kr

홈페이지 내용발췌 :

AcroEdit는 지금도 개발중이며 전문 텍스트 에디터를 표방하여 지속적으로 성능 향상을 위하여 노력하고 있습니다.

AcroEdit는 공개 프로그램이기 때문에 개인, 직장, 공공기관등 어디에서든 누구든지 사용하실 수 있습니다.

Desy Edit : http://www.desyedit.com/

홈페이지 내용발췌 :

DesyEdit를 'Funcware'라 제창합니다.

'Funcware'란 DesyEdit의 개발자가 직접 만든말로써, Freely Use No Complain의 첫머리글자만을 따서 만든 말 입니다.

말 그대로 누구나 사용할 수 있지만, 어떠한 불평도 하지 않는다는 뜻입니다.

그러나 사용자 여러분의 관심에서 나오는 질타는 달게 받겠습니다
 

CD버닝 프로그램

CDBurnerXP : http://www.cdburnerxp.se/

홈페이지 내용발췌 : Everyone, even companies, can use it for free.

InfraRecorder : http://sourceforge.net/projects/infrarecorder/

홈페이지 내용발췌 : License : GNU General Public License (GPL)


가상 드라이브 프로그램

Gizmo : http://arainia.com/software/gizmo/

프로그램 -> Help -> Documentation

: Gizmo is Freeware and is made avilable for commercial and personal use at absolutlely no cost whatsoever.
 

그래픽 툴 프로그램

GIMP : http://www.gimp.org

홈페이지 내용 발췌 : GIMP is an acronym for GNU Image Manipulation Program.

Paint.net : http://www.getpaint.net/

홈페이지 내용 발췌 :
Q: Can I use Paint.NET for business, commercial, or government use? Or is it only free for "personal" use?
A: Yes -- Paint.NET is free for all uses including personal, business, commercial, government, and school. There has been some confusion lately around the license and its seemingly hybrid MIT / Creative Commons status. Rest assured that you really only have to dive deeper into the legalities of the license if you are planning to do something such as distributing a modified version of Paint.NET. Usually this involves downloading the source code, or disassembling / decompiling stuff. If you're just installing and using Paint.NET, then there's really no need to worry about that.

사진편집 프로그램

포토스케이프 : http://photoscape.co.kr/ps/main/index.php

홈페이지 내용 발췌 : 포토스케이프는 집,회사,학교,학원에서 모두 무료입니다.


이미지 뷰어 프로그램

다씨 : http://datools.kr/

홈페이지 내용발췌 : 다씨(DaSee), 다집(DaZip), 다FTP(DaFTP)는 언제, 어디서, 누구나 기업체/관공서 상관없이 모든 사람이 무료로 사용할 수 있는 프리웨어입니다.

꿀뷰 : http://www.kipple.pe.kr/win/honeyview3
홈페이지 내용 발췌 : 꿀뷰3는 기업이나 관공서/법인/학교/게임방/무인도 등에서 맘대로 설치해서 사용 가능한 프로그램 입니다. (소프트웨어 불법 사용 단속에 걸리지 않는다는 의미)


아무쪼록 이 글 보시고, 회사 전산담당자와 상의하여 [소잃고 외양간 고치는일] 없이,

미리 미리 준비하여 주시기 바랍니다.

읽어주셔서 감사합니다.


출처 :  http://www.parkoz.com/zboard/view.php?id=my_tips&page=1&page_num=50&select_arrange=headnum&desc=asc&sn=off&ss=on&sc=off&divpage=3&keyword=&no=12886&category=&show=all

반응형
Posted by blueasa
, |

1. 개요

오브잭트 자원관리를 하다보면 오브잭트가 죽거나 더이상 어떤이유로 필요없어질 경우에 리스트에서 제거를 하려면 순회도중 죽었는지 검사해서 루프를 도는 도중 삭제를 해야한다.

 

2. 구현

it = list1.begin();
while(it != list1.end())
{
    if(*it == 죽었나?) list1.erase(it++);
    else ++it;	 	   
}
3.원리
원리는 먼저 it값이 erase()로 복사되어 넘어가고, 
it++가 실행되고, 마지막으로 erase()로 넘어간 복사된 it이 할 일을 마치고 무효화됨. 



[출처]
stl list 순회도중 삭제하기|작성자 도플광어
반응형
Posted by blueasa
, |



1. 개요

카툰랜더링이나 캐릭터 선택효과에 주로 쓰이는 실루엣 기법을 알아본다.

 

2.경계선 메쉬 만들기

메쉬를 구성하는 모든 edge들을 퇴축 사각형(넓이가 0인 사각형)으로 재구성한다.

 A        B
 *--------*
 |  edge  |
 *--------*
 C        D

 

초기에 A==C , B==D 이 다.

 

이부분은 silhouetteEdges.cpp,silhouetteEdges.h가 처리를 해준다.

 

SilhouetteEdges객체 초기화는 아래와 같이  메쉬를 넣어서 만든다.

ID3DXBuffer* adjBuffer = 0;
D3DXCreateTeapot(Device, &Teapot, &adjBuffer); 
OutLineShader::g_pMesh = new SilhouetteEdges(Device, Teapot, adjBuffer);
SAFE_RELEASE(adjBuffer);

 

랜더방법은 아래와같이 쉐이더 적용후에 render함수를 호출해준다.

 

pd3dDevice->SetVertexShader(OutLineShader::g_pShader);

...

OutLineShader::g_pMesh->render();

 

 

 

3. 실루엣 외각선 구분하기

두개의 면을 공유하는 외각선이 있을때 관찰자 기준으로 두개의 면이 서로 다른방향을 보면 그 외각선은 실루엣 외각선이다.

이부분은 outline.hlsl 이 처리한다.

 

 

4. 결론




출처 : http://gbox2.blog.me/100050813839

반응형
Posted by blueasa
, |

매크로는 C와 C++에서 제공되는 꽁수같은 기능이라고 할 수 있습니다.

꽁수같다라고 한 이유가  매크로는 사용자의 편의와 동시에 많은 위험성을 초래하기 때문이죠.

그래서, 대부분의 서적에서는 매크로의 사용을 자제하고 인라인(inline)과 상수형(const)을 더 지향하기도 합니다.

 

하지만, 이는 단순히 매크로의 위험성 때문이며 그 위험성의 간단한 예를 들자면,

 

#define POW( A ) A * A        // 정의했을 경우

...

POW( 10 + 10 )                // 사용자의 의도는 20 * 20 입니다.     하지만 결과는,

10 + 10 * 10 + 10             //10 + 100 + 10 = 120 이죠.

 

또한, 상수형 같은 경우는 디버깅이 불가능하다는 점도 있죠. 최근에 좋은 개발 툴은 매크로 변수를 추적도 가능하다고 합니다만... 비주얼 스튜디오 2008에서도 아직 안되더군요. :|

 

어쨌든, 그런 위험성을 제거할 수 있고 개발자 편의로 매크로를 마음껏 사용할 수 있다면, 구지 매크로를 사용을 자제할 필요가 없다고 봅니다.

 

결론은, 매크로의 사용여부는 개발자 자신에게 넘기도록 하겠고, 오늘은 매크로의 비법들에 대해서 한번 살펴보도록 하겠습니다.

매크로 사용여부는 다 알고 계신다고 가정하고, 사용 설명은 따로 하지 않겠습니다. 간단한 예를 보면 쉽게 이해가 될 겁니다.

 

#1) 열거형을 문자열로

 #define CaseEnum( A )      case( A ) : LogMsgToFile( #A )

 

switch( msg ) {

  CaseEnum( MSG_One );

    ...

    break;

  CaseEnum( Msg_Two );

    ...

    break;

  default:

    ...

    break;

}

 

/*************컴파일 전처리가 끝나면, 위의 소스는 다음과 같이 대체 됩니다.***********************/

 

switch( msg ) {

  case( MSG_One ): LogMsgToFile( "MSG_One" );

    ...

    break;

case( MSG_Two ): LogMsgToFile( "MSG_Two" );

    ...

    break;

  default:

    ...

    break;

}

 

 #2) 두 인자를 하나의 값으로 합치기

#define CAT( A, B )    A ## B

 

value = CAT( 1, 2 );

 

/*************컴파일 전처리가 끝나면, 위의 소스는 다음과 같이 대체 됩니다.***********************/

 

value = 12;

 

 #3) 표준 assert에 의미있는 메세지 추가하기

#define ASSERT_MSG( A, B )  assert( a && b )  

 

ASSERT_MSG( time > 0, "time must be bigger than zero" );

 

/*************컴파일 전처리가 끝나면, 위의 소스는 다음과 같이 대체 됩니다.***********************/

 

assert( time > 0 && "time must be bigger than zero" ); 

 

//사용에 있어서 큰 차이는 없지만 매크로가 더 사용자 직관적이지 않나요?

 

 #4) 컴파일 시점의 assert

//애초에 제한 조건에 벗어나면 컴파일 오류를 발생 시킵니다.

#define CASSERT( A ) typedef char __C_ASSERT__[ (A) ? 1: -1 ]

 

CASSERT( sizeof( MyEnum ) == sizeof( unsigned int ) );

 

/*************컴파일 전처리가 끝나면, 위의 소스는 다음과 같이 대체 됩니다.***********************/

 

//만약 MyEnum의 크기가 16이라고 가정했을 때,

typedef char __C_ASSERT__[ ( 16 == 4 ) ? 1: -1 ]

 

16 == 4는 거짓이며 따라서 __C_ASSERT[ -1 ] 이라는 형을 정의하려고 합니다.

하지만, -1의 크기의 배열 정의는 컴파일러 입장에서 불가능하기 때문에 잡아낼 수 있죠. 

 

#5) 배열의 원소를 구하기

//자바 같은 경우는 배열의 원소 갯수를 알 수 있지만 C/C++ 에서는 기본적으로 제공되진 않습니다. 

#define NUM_ELEMENT( A ) ( sizeof( A ) / sizeof( ( A[ 0 ] ) )

 

int a[ 10 ]

int nElement = NUM_ELEMENT( a );

 

/*************컴파일 전처리가 끝나면, 위의 소스는 다음과 같이 대체 됩니다.***********************/

 

int a[ 10 ]

int nElement = 40 / 4;

 

#6) __LINE__을 문자열로

// 기본적으로 정의되어 있는 유용한 매크로들 입니다.

__LINE__ // 컴파일 시점의 행 번호를 의미하는 정수

__FILE__ // 컴파일 되는 파일 이름을 담은 문자열

__DATE__ // 컴파일 될 때의 날짜를 담은 문자열

__TIME__ // 컴파일 될 때의 시간을 담은 문자열

 

//이들을 디버깅 시 유용히 활용할 수 있습니다.

#define TO_MSG( X ) #X

 

#define __FILELINE__ __FILE__" ( " TO_MSG(__LINE__) " ) "           //VC++에서는 안될 수도 있음

 

/*************컴파일 시 다음과 같이 출력됩니다.***********************/

c:\project\main.cpp ( 105 )

 

 

 

-참고 : Game Programming Gems 3 ( 정보문화사 )-


 
[출처] 매크로 마법 (Macro)|작성자 Hermet

반응형
Posted by blueasa
, |

[펌] !!a

Tip & Tech / 2011. 6. 8. 01:41

최근 어느 오픈 소스를 살펴 보다가 a = !!b 와 같은 코드를 보게 되었습니다.

 

곰곰히 생각해보니... 그래도 도대체 왜 하는건지? -_-a

 

a와 b의 타입이 unsigned char라고 하면, 결국 a = !!b 는 a = b 인거잖아?

 

 

사실 일부 c와 같은 언어는 boolean 타입을 별도로 지원하지 않으므로,

 

2바이트의 char형을 이용하며, 엄밀히 boolean의 0 과 1 이라는 두가지 상태 그 이상의 것이 될 수도 있는 것이지요.

 

즉, b는 0 ~ 255 사이의 값이 될 수도 있으며

 

그래서 !!b는 b가 어떠한 값이든 간에 0이 아닌 이상 b의 값을 1로 바꾸어 줄 겁니다.

 

b 가 25 라고 가정할 때,

!b 는 0

!!b 는 1

 

오호...

 

그럼 a = !!b 대신 a = b를 이용했을 땐, 어떤 문제가 발생할 수 있을까?

 

 

#define TRUE 1

#define FALSE 0

 

typedef unsigned char BOOL;

 

BOOL sound_state = FALSE;

 

void set_sound_state( BOOL state ) {

    sound_state = state;

}

 

BOOL get_sound_state() {

   return sound_state;

}

 

void test() {

    

    //사용자가 실수로 TRUE 대신 임의의 값을 집어 넣었습니다.

    //그런다고 해도 컴파일 오류는 안나고 심지어 컴파일 경고도 발생하진 않겠죠.

    set_sound_state( 123 );

   

     //결국, 기대하던 OK는 출력될리가 없습니다.

     if( get_sound_state() == TRUE ) {

        printf("OK!\n");

     }

 

}

 

사용자는,  값이 있으면 TRUE이겠지 라고 충분히 착각할 수도 있습니다.

 

결국, 우리가 정의한 TRUE는 1이기 때문에  123 == 1 비교식에서 실패나겠죠.

 

따라서, 다음과 같이 수정을 해준다면

 

 

void set_sound_state( BOOL state ) {

    //심지어 state가 123 이어도 값을 1로 바꿔줍니다.

    sound_state = !!state;

}

 

자, 이제 만사 OK!


[출처]
 !!a|작성자 Hermet

반응형
Posted by blueasa
, |

간단히 메모리 릭 발생여부를 알아내고 이를 해결하는 방법에 대해서 알아봅시다.

 

이는 MS 사에서 CRT(C Runtime) 라이브러리로 제공해는 CRTDBG 를 이용할 겁니다.

생각보다 쉬운 반면 그 기능은 막강하지요.

 

일단 프로그램 정의부에 다음과 같이 추가합니다.

 

#include <crtdbg.h>

#define CRTDBG_MAP_ALLOC

 

#ifdef _DEBUG

#define new new( _NORMAL_BLOCK, __FILE__, __LINE__ )        //궁금하시면 제 게시글 중 <매크로 마법> 편을 보세요.

#endif

 

이제 메인 진입 부 처음에 다음과 같이 선언합니다. 일반 main() 이라고 가정합니다. 물론 WinMain() 일 수도 있습니다.

 

void main() {

 

    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

 

    //  .... 메모리를 동적 할당하는 무언가의 작업을 하겠죠

 

}

 

추가로 설명하자면, _CrtSetDbgFlag 설정 비트 필드 값은 다음과 같습니다.

 

_CRTDBG_ALLOC_MEM_DF : 디버그 힙 메모리 할당을 허용합니다. 또한 _CLIENT_BLOCK과 같은 사용자 정의 메모리 블럭을 사용합니다.

 

_CRTDBG_LEAK_CHECK_DF : 프로그램 종료 시 자동으로 메모리 릭을 찾고 이를 출력해 줍니다. 이는 _CrtDumpmemoryLeaks 함수를 호출한 것과 같은 결과입니다.

 

이제 프로그램을 디버그 모드로 실행하고 종료합니다. 만약 동적 메모리 해제를 제대로 안해줬다면 다음과 같은 결과가 결과 화면에 출력됩니다.

 


 

우리에게 필요한 것은 바로 빨간색 선을 그은 정보입니다. 우리는 이 번호를 이용해 메모리 릭이 일어나는 부분을 찾아갈 수 있습니다.

그러나  중요한 점은 똑같은 환경에서 다시 실행했을 때도 메모리 릭 현상 결과가 같아야 한다는 점입니다. 그렇지 않으면, 매번 실행할 때마다 메모리 릭이 발생한 위치가 달라지고 따라서 위 번호도 달라져 버립니다.  따라서, 다른 작업을 하지 마시고 디버깅 작업만 하시길 바랍니다.

 

일단 위 9637 번호를 이용해서 메모리 릭이 일어나는 곳을 찾아가겠습니다. 이제 다시 main 첫부분에 다음과 같이 추가합니다.

 

void main() 

 

     _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

    _CrtSetBreakAlloc( 9637 );

 

    //  .... 메모리를 동적 할당하는 무언가의 작업을 하겠죠

 

}

 

그리고 다시 디버그 모드로 실행을 하면 9637에 지시하는 똑같은 메모리 번지를 알아서 브레이크 포인터를 걸어줍니다.

우리는 그 부분의 소스를 보고 콜 스택을 추적해 가면서 메모리 릭을 감지하고 해결할 수가 있죠.

 

이런식으로 출력창에 출력되었던 다른 메모리 릭도 모두 찾아 해결하시면 됩니다.

 

 

릴리즈 배포 전, 메모리 책임은 프로그래머의 미덕이지 않을까요?

 

 

 

- 참고 : MSDN -


 
[출처] C Runtime 환경의 메모리 릭 잡는 방법 ( Memory Leak )|작성자 Hermet

반응형
Posted by blueasa
, |

1. 개요

_CrtDumpMemoryLeaks() 라는 함수를 이용해서 메모리 누수와 누수 지점을 알아내는 기법을 알아본다.

 

2. 탐지하기


#define CRTDBG_MAP_ALLOC


#include <crtdbg.h>

 

void main()

{

   char *ptr = new char[20];

 

   _CrtDumpMemoryLeaks();

}

 

 

 

여기서 {100} 라는 숫자를 보자...

{100 } 이라는 위치에서 할당받은 메모리가 해제가 안된체로 남아있다는 말이기 때문에 그위치에서 브래이크걸도록 만들면

원인을 일으킨 위치를 알아낼수있다.

 

 

void main()

{

  _CrtSetBreakAlloc(100);

  

  char *ptr = new char[20];

 

   _CrtDumpMemoryLeaks();

}

 

 

CrtSetBreakAlloc함수를 시작위치에 두고 다시 컴파일 하여 실행을 시켜보자.

 


 

 

  char *ptr = new char[20]; 위치에서 브래이크 걸릴것이다.

 

이런식으로 메모리 누수를 잡아낼수있다.

 

 

 

 

3. 주의사항

 

mfc용 어플리캐이션은 자동으로 메모리 누수 탐지가 되지만 일반 원도우 어플이나 콘솔어플은 이방법을 사용 해야만 메모리 누수를 알수있다.

 

_CrtDumpMemoryLeaks(); 가 호출되는 시점에서 해제 안된 메모리를 덤프하므로 꼭 프로그램 종료 직전에 써줘야 정확한 메모리 누수여부를 알수잇다.

 

_CrtDumpMemoryLeaks();

delete somePtr;

 

이렇게 되면 메모리 릭이 덤프된다.

 

또한

STL 사용시 제데로 릭을 검출 하지못하고 무조건 메모릭으로 판단하는 경우가 있다.

 

void main()

{

  std::string str("http://jga.or.kr");
  _CrtDumpMemoryLeaks(); 
}

 

이코는 문제가 없지만 str이 아직 중괄호 범위를 벋어나지 않았으므로 여전히 해제가 안된것으로 간주하여 메모릭으로 출력한다.

 

이때는 ::_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); 를 사용해서 릭을 검출할수있다.

 

void main()

{

  ::_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

  std::string str("sasa");

  char *ptr = new char[20];

  
  //_CrtDumpMemoryLeaks(); 
}

이렇게 해주면 str에 대해서는 메모리릭이 발생하지않는다.


출처 : http://cafe.naver.com/jcga/883

반응형
Posted by blueasa
, |