반응형

inline : 컴파일시 알아서 인라인으로 함수를 만들지의 여부를 결정

forceinline : 무조건 inline 으로 생성

반응형
반응형

assert

assert는 코드 차원에서 프로그램의 안정성을 높이는 역할을 한다. assert라는 단어를 영한 사전에서 찾아 보면 "단언하다, 확실히 하다"라는 뜻을 가지고 있는데 코드가 정확하게 동작할 수 있는 상황이라는 것을 확인한다. 함수는 입력과 출력을 가지는데 입력이 정확하면 출력도 항상 정확하지만 호출부에서 틀린 값을 주면 함수를 아무리 잘 만들어도 안정적인 동작을 할 수 없다. 예를 들어 다음 함수를 보자.

int divide(int a, int b)

{

return a/b;

}

이 함수는 인수로 주어진 두 정수 a와 b의 나누기 연산을 하여 그 결과를 리턴하는데 divide(6,3)을 호출하면 당연히 2라는 결과를 리턴할 것이다. a와 b만 정확하다면 이 함수가 절대로 틀릴 수 없겠지만 만약 나누는 수 b가 0이면 이 함수는 치명적인 에러를 일으키고 다운되어 버릴 것이다. 이런 에러를 방어할 때는 통상 if문을 사용하는데 if는 어디까지나 에러를 피해 다니는 방법이지 에러를 근본적으로 수정하는 방법은 아니다.

이런 에러를 수정하려면 결국 호출부가 b로 0을 전달하지 않도록 해야 하며 개발자는 이런 상황이 발생했을 때 호출부를 수정해야 한다. divide 함수에 필요한 코드는 b가 0이 되었을 때를 적발해 내는 감시 코드인데 이럴 때 assert문을 사용한다. assert는 assert.h 헤더 파일에 정의되어 있는 매크로 함수이므로 이 헤더 파일을 인클루드해야 한다.

: Assert

#include <Turboc.h>

#include <assert.h>

int divide(int a, int b)

{

assert(b!=0);

return a/b;

}

void main()

{

divide(6,3);

divide(1,0);

}

assert 함수는 표현식을 인수로 전달받아 이 인수가 참인지를 점검한다. 조건이 참이면 이 함수는 아무 일도 하지 않지만 거짓이면 에러 발생 위치와 표현식 등으로 구성된 상세한 에러 메시지를 출력하고 프로그램을 강제로 종료시킨다. assert는 괄호안의 조건식이 확실히 맞는지 확인하는 역할을 하는데 assert (b!=0); 문은 b가 0이 아니라는 것을 확실히 하라는 뜻이다. 특정 시점에서 반드시 참이어야 하는 조건을 assert 의 인수로 작성한다. 그렇다면 다음과 같이 쓰는 것과는 무엇이 다를까?

int divide(int a, int b)

{

if (b==0) exit(-1);

return a/b;

}

이 코드는 b가 0일 때 프로그램을 강제로 종료함으로써 아래의 a/b 연산을 하지 않도록 하기는 하지만 왜 프로그램이 종료되었는지는 알려 주지 못한다. 반면 assert는 버그가 있다는 것 뿐만 아니라 프로그램이 어디서 어떤 이유로 종료되었는지를 자세히 알려준다. 이 예제의 main에서 b로 0을 넘기고 있으므로 이대로 실행하면 다음과 같은 에러 메시지가 출력된다.

Assertion failed: b!=0, file C:\CExam\Assert\Assert.cpp, line 6

Assert.cpp의 6번째 줄에서 b!=0 조건이 맞지 않아서 프로그램이 종료되었다는 것을 표시하고 있다. 콘솔 프로젝트는 이 메시지가 stderr 표준 출력(결국 화면)으로 나타나지만 그래픽 프로젝트에서는 다음과 같은 대화상자가 나타나며 이 대화상자로 에러 위치와 원인을 정확하게 알 수 있다.

개발자는 이 메시지를 받았을 때 다시 시도 버튼을 누른 후 중단된 시점의 콜 스택과 주요 변수의 상태를 확인하여 에러의 원인을 쉽게 알 수 있다. 위치만 알면 원인과 해결책은 금방 파악된다. 디버깅은 버그를 고치는 작업이라기보다는 버그를 찾아 내는 것이며 찾기만 하면 고치는 것은 아주 쉽다.

그렇다면 assert가 없을 때와는 또 무엇이 다를까? 어차피 이 예제를 실행하면 바로 다음 행의 나누기 연산식에서 에러가 발생하며 프로그램은 강제로 종료된다. 프로그램이 죽는다는 것을 알면 디버거로 단계 실행해서 죽은 위치와 원인을 알아 내는 것도 가능하다. 그러나 예외가 발생하는 시점과 예외의 원인이 발생하는 시점이 이 예제처럼 인접해 있는 경우보다는 그렇지 못한 경우가 훨씬 더 많다. 다음 예제를 보자.

: Assert2

#include <Turboc.h>

#include <assert.h>

size_t getsize()

{

int size;

size=0;

return size;

}

void main()

{

char *p;

int size;

size=getsize();

p=(char *)malloc(size);

strcpy(p,"test");

free(p);

}

getsize 함수는 어떤 대상의 크기를 조사하며 main은 이 함수가 조사한 크기만큼 메모리를 할당해 사용한다. 어떤 에러로 인해 getsize가 크기를 제대로 조사하지 못해 0으로 조사했다고 하자. 이럴 때 프로그램이 죽는 위치는 getsize가 아니라 이 잘못된 크기를 사용하는 곳인데 이 예제의 경우 strcpy 또는 free에서 죽을 수 있다. 에러의 원인은 getsize가 제공했지만 이 에러가 문제가 된 곳은 main인 것이다. 이럴 때 getsize에 assert 문을 작성한다.

size_t getsize()

{

int size;

size=0;

assert(size >= 6);

return size;

}

이렇게 해 두면 getsize에서 문제가 발생하는 즉시 assert가 이대로 두면 위험하다는 것은 적극적으로 알린다. 좀 더 대규모의 프로젝트에서는 최초 발생한 에러가 수천줄 이후에나 말썽을 일으키기도 하는데 이럴 때 죽은 자리의 코드만 봐서는 어디서부터 꼬였는지 찾기 대단히 어렵다. 그래서 에러의 원인이 될만한 곳에 assert를 삽입하여 미리 오동작을 발견하고자 하는 것이다.

assert는 가급적 많이 사용하는 것이 좋다. 조금이라도 의심이 가는 부분에 대해서는 항상 assert문을 삽입하여 조건을 확실히 만족하는지 점검해야 한다. assert는 에러를 잡기 위한 일종의 덫인 셈인데 덫을 많이 놓을수록 에러가 걸려들 확률은 높아지고 프로그램의 안전성이 향상된다. assert는 또한 문서화에도 도움을 주는데 코드를 읽는 사람에게 함수가 동작하기 위한 전제 조건을 잘 설명한다. 주석보다 오히려 assert가 더 간결한 설명문이다.

assert는 아무리 많이 써도 최종 프로젝트의 성능이나 크기와는 상관이 없다. 왜냐하면 assert 는 조건부 컴파일로 정의되어 있는 매크로 함수이기 때문이다. assert 매크로가 어떻게 정의되어 있는지 assert.h 헤더 파일을 보자. 이 정의문에 있는 조건부 컴파일 지시자와 # 연산자 등에 대해서는 다음에 상세하게 배울 것이다.

#ifdef NDEBUG

#define assert(exp) ((void)0)

#else

#define assert(exp) (void)( (exp) || (_assert(#exp, __FILE__, __LINE__), 0) )

#endif /* NDEBUG */

디버그 버전일 때 assert는 인수로 주어진 exp를 평가하고 이 값이 참이면 _assert 함수를 호출한다. 쇼트 서키트 기능에 의해 exp가 참이면 전체 식이 이미 참으로 판명났으므로 _assert 함수는 호출되지 않는다. _assert는 에러가 발생한 수식과 위치를 콘솔 또는 대화상자로 출력하고 프로그램을 종료하는 진짜 함수이되 exp가 거짓일 때만 호출된다.

릴리즈 버전일 때 assert는 그냥 0으로 평가되는 빈 문장이므로 프로그램의 속도를 감소시키지도 않고 크기를 늘리지도 않는다. 조건부 컴파일 지시자에 의해 assert를 한 번에 솎아낼 수 있는 장치가 마련되어 있으므로 필요한 곳에 마음껏 써도 상관없다. 그래서 완벽주의를 지향하는 개발자의 소스를 보면 코드만큼이나 assert가 많이 포함되어 있는 경우도 있다. 다음은 assert문의 주의 사항이다.

assert 매크로는 디버거 버전에서만 컴파일되므로 assert의 인수로는 생략해도 상관없는 조건식만 넣어야 한다. 릴리즈 모드에서도 실행해야 하는 의미 있는 동작을 assert 문에 작성해서는 안된다. 다음 코드를 보자.

assert((pSet=DoQuery())!=NULL);

pSet의 결과 출력

이 코드는 데이터 베이스에 질의를 보내 결과 셋을 받는데 결과 셋이 NULL이 아니라는 것을 확인하기 위해 assert문을 사용했다. 디버거 모드에서는 이 문장이 제대로 실행되지만 릴리즈 모드로 바꾸면 DoQuery 함수가 호출되지 않으므로 pSet은 쓰레기값을 가질 것이다. 이 코드가 확인하고자 하는 것은 결과 셋이 제대로 조사되었는가 아닌가이므로 DoQuery 호출문은 빼고 pSet값을 비교하는 조건문만 assert에 넣어야 한다.

pSet=DoQuery();

assert(pSet!=NULL);

pSet의 결과 출력

일단 DoQuery를 호출하여 결과를 조사하고 assert문으로 결과가 제대로 조사되었음을 확인했다. pSet!=NULL은 단순한 조건문일 뿐이므로 릴리즈 모드에서 이 조건문이 빠져도 아무 상관이 었다. assert는 어디까지나 확인용 함수일 뿐이므로 변수의 값을 바꾸거나 프로그램의 상태를 변경하는 코드는 assert안에 둘 수 없다.

assert는 절대로 발생해서는 안되는 조건에 대해서 사용하는 것이지 정상적인 에러 상황을 처리하는 문장이 아니다. 위 예에서 DoQuery 함수는 반드시 결과를 돌려 주는 것으로 가정하고 있으며 만약 질의 결과에 해당하는 레코드가 하나도 없다면 빈 결과셋이라도 리턴할 것이다. DoQuery가 실패하는 상황도 정상적이라면 assert 대신 if문을 사용해야 한다. 다음 예를 보자.

ch=getch();

assert(isalphs(ch));

입력한 영문자에 따른 작업

이 코드는 ch로 반드시 영문자만 입력하도록 요구하며 사용자는 반드시 영문자 중 하나를 입력하도록 강요한다. 사용자가 설사 입력을 잘못했다고 해서 프로그램이 종료되어서는 안되므로 여기에 사용된 assert문은 적합하지 않다. 잘못 입력했으면 다시 입력하라는 메시지를 출력하는 것이 정상적이지 프로그램이 종료되면 어떻게 되겠는가? 사용자는 언제나 실수할 가능성이 있으며 이런 상황은 아주 정상적인 처리 과정일 뿐 예외가 아니므로 여기에는 if문을 사용해야 한다.

assert 문에 조건을 작성할 때는 가급적이면 한 조건당 하나의 assert를 쓰는 것이 좋다. 줄 수를 줄이고자 여러 개의 조건을 하나의 assert에 넣는 것은 좋지 않다.

assert (a!=0 && p!=NULL && b==0);

이렇게 하면 셋 중 하나라도 거짓일 때 에러 메시지가 출력되기는 하지만 에러 메시지만으로는 셋 중 어떤 문제로 인해 프로그램이 정지되었는지 바로 알 수 없다. 세 개의 assert 문으로 각각 분리해 놓으면 어떤 조건이 거짓인지를 바로 알 수 있다. assert는 아무리 많아도 성능에 영향을 주지 않으므로 굳이 한 줄로 압축할 필요없이 에러 메시지로부터 원인을 바로 알 수 있도록 하는 것이 좋다.

C 라이브러리가 제공하는 표준 assert 매크로 외에도 각 라이브러리나 언어, 개발툴이 제공하는 고유한 확인 함수들이 있다. 예를 들어 MFC 라이브러리는 ASSERT, _ASSERT 등의 매크로를 제공하는데 약간의 기능 차이와 출력하는 메시지의 내용이 다를 뿐 사용하는 방법이나 목적은 동일하다.

출처 : www.winapi.co.kr

반응형

'프로그래밍(Programming) > c++, 11, 14 , 17, 20' 카테고리의 다른 글

GetPrivateProfileStringA  (0) 2012.10.31
forceinline VS inline  (0) 2012.10.31
enum with namespace  (0) 2012.10.31
eula.1028.txt 의 정체  (0) 2012.10.31
try , catch 예외처리를 쓰는 경우..  (0) 2012.10.31
반응형

namespace TYPES{

enum TYPE{ ZERO,ONE,TWO }; //열거형 선언

// 0 , 1 , 2 // 0,1,2 의 순인 n=n+1 으로 증가한다 , 단 n = 정수
};

int main(){

TYPES::TYPE m_data;

m_data=TYPES::TWO; //m_data 는 이름공간 안에 있는 열거형의 값을 담을 수 있는 열거형 변수

cout<<m_data<<endl;
}

출력 결과

2

* 이름 공간을 사용하는 이유 : 거대한 프로젝트에서 enum 은 이름 중복을 발생시킬 수 있는 문법중 하나인데

이를 효율적으로 방지하고자 이름공간(namespace) 를 사용한다

반응형
반응형

http://doodoori2.tistory.com/197

eula.1028.txt
eula.1031.txt
eula.1033.txt
eula.1036.txt
eula.1040.txt
eula.1041.txt
eula.1042.txt
eula.2052.txt
eula.3082.txt
globdata.ini
install.exe
install.ini
install.res.1028.dll
install.res.1031.dll
install.res.1033.dll
install.res.1036.dll
install.res.1040.dll
install.res.1041.dll
install.res.1042.dll
install.res.2052.dll
install.res.3082.dll
VC_RED.cab
VC_RED.MSI
vcredist.bmp


Visual C++ redistributable package 가 배포되면서 생기는 임시 파일이란다
압축을 그냥 무식하게 C:\ 혹은 D:\ 에다가 풀어버리고
설치한다음에 지우지 않은 것.

이미 설치된 상황일테니까 그냥 지워주면 된다.


http://answers.microsoft.com/en-us/windows/forum/windows_7-system/what-is-eula1028text-on-c/042cf4d8-0425-430f-88ca-b35da9439cfd

반응형
반응형

1.

클래스 내에서 enum 으로 설정한 값을 리턴하여 catch 구문에서

enum 명으로 예외처리할 수 있다

try catch 구문에서는 int 의 0 과 enum 의 0 을 다른 것으로 인식 할 수 있다 단 enum 의 변수명으로 받아야 한다

2. 생성자, 소멸자에서 에러가 나는 경우 try, catch 구문으로 처리 할 수 있다

#include "stdafx.h"

class a{
public :
enum DD{ FIRST=0 };

DD get(){ return FIRST; }
int getzero(){ return 0; }

};

int _tmain(int argc, _TCHAR* argv[])
{
a ai;

try{
//throw ai.get();
throw ai.getzero();

}catch( a::DD data ){
int ddd=data;
ddd+=1;
}catch( int data ){
int ddd=data;
ddd+=1;
}


return 0;
}

반응형
반응형










이클립스로 c, c++도 자바 코딩만큼 쉽게 하자. 

2009/03/28 16:44

복사http://aboutk.net/140065537334


많은 자바 사용자가 애용하는 IDE, 이클립스!!

 

이클립스에서 c와 c++ 코딩, 컴파일까지 담당해주는 ide도 내놓았다.

내놓은지는 오래됐으나, CDT를 따로 설치해줘야했다.

근데 GANYMEDE버전부터는 CDT를 따로 다운받아서 설치하지 않고도,

단순히 이클립스의 업데이트 기능으로 cdt 플러그인을 받아서 사용할 수 있게 되었다.

 

 

설치방법을 한번 살펴보도록 하자.

 

1. 이클립스를 실행한다.

 

 

2. Help 메뉴에, Software Updates에 들어간다.

 

 

3. Software Updates 메뉴에 들어가면

Eclipse C/C++ Development Platform과 Eclipse C/C++ Development Tools를 볼 수 있는데

둘 다 우측 상단에 보이는 Update 버튼을 눌러서 업데이트 시켜준다.

 

업데이트를 눌러줌으로서 최신의 cdt로 업데이트 해주거나, 또는, cdt가 설치되있지 않을시에 자동적으로 설치를 해준다.

 

 

그러면 이제 완성.

 

새로 프로젝트를 만들때 C 또는 C++를 구분해서 만들고,

클래스 파일을 만들고 나서 코딩을 한다.

프로그램 코딩이 끈나면 이클립스 프로그램의 상단에 보면 "컴파일 & 실행" 버튼이 있다.

위의 스크린샷에 보면 빨간색으로 표시되어있는 버튼이다.

 

이클립스의 최대 강점을 꼽자면,

사용자가 컴파일 과정을 따로 해주지 않아도 된다는것이다.

실행버튼을 한번 클릭함으로서 컴파일의 수고를 덜고

곧바로 실행 결과를 볼 수 있다.

 

이클립스를 사용함으로서

메모장이나 텍스트플러스와 비교했을때

오타와 같은 문법적인 오류가 발생했을시에

오류 표시가 바로바로 나오기때문에

 

코딩시 오류를 찾는데 소비되는 시간을 많이 절약할 수 있다.

 

그리고 잦은 테스트로 인해 소비되는 컴파일 시간을 많이 절약할 수 있다.

반응형
반응형

http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=51&MAEULNO=20&no=8454

MiniDump를 위한 심볼/소스 서버 구성하기

팀에서 사용하려고 만든 문서 올려봅니다.

SVN을 기준으로 작성했으나.. 소스세이프나 CVS등도 가능합니다.

수정/개선 사항 있으면 코맨트 부탁드립니다.

---------------------------------------------------------------------------------------------------------------

개발한 응용프로그램을 배포하면 뜻하지 않게 프로그램이 죽는 문제를 만나게 된다. 이런 경우 어디에서 왜 죽었는지를 파악하기 위해 dump파일을 생성하게 된다.

그러나 이렇게 생성된 dump파일도 해당 프로세스의 버전과 동일한 .pdb 및 소스가 없다면 무용지물이 된다.

제품을 출시한 후에 소스를 끊임없이 수정하는 상황에서는 소스 및 pdb 파일의 관리가 어려워진다.

이 문서는 생성된 dmp파일이 올바른 pdb및 소스를 자동으로 찾도록 해서

관리를 쉽게 할 수 있는 심볼/소스 서버를 구축하는 방법을 소개한다.

1. Debugging Tools for Windows 설치하기

서버를 구성하기 위해서는 symchk, symstore 등 심볼을 관리하는 프로그램이 필요하다. 이것은 Debugging Tools for Windows에서 제공하고 있다.

아래의 주소에서Debugging Tools for Windows를 최신 버전으로 다운로드 해서 설치한다.

32비트http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx
64
비트http://www.microsoft.com/whdc/devtools/debugging/install64bit.mspx#

그러나 2010/02/26버전부터 WDK(Windows Driver Kit)에 통합됐기 때문에 32/64에 무관하게 아래의 주소에서 다운로드 받으면 된다.

http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=36a2630f-5d56-43b5-b996-7633f2ec14ff

2. OS심볼의 자동 다운로드 설정

WinDbg Visual Studio에서 OS exe/dll 파일의 심볼을 자동으로 다운로드 할 수 있도록 다음과 같이 시스템 변수를 등록해야 한다.

변수 이름 : _NT_SYMBOL_PATH
변수 값 : SRV*E:\Debugging\Symbols\Os\*http://msdl.microsoft.com/download/symbols

빨간색으로 된 부분은 각자의 환경에 맞게 설정해야 한다. 위의 경로는 OS의 심볼들을 위한 것이고 후에 우리가 만든 제품의 심볼을 저장할 경로도 설정할 것이므로 Symbols밑에 OS로 폴더를 구분하는 것을 추천한다.

3. 심볼/소스 서버의 경로 설정

우리가 작업하는 프로젝트의 위치는 가변적이기 때문에 심볼/소스 서버의 관리 프로그램의 경로를 설정한다.(다음 페이지 그림 참조)

64비트의 경우 기본 경로는 아래와 같다.
(
심볼 서버
) C:\Program Files\Debugging Tools for Windows (x64)\
(
소스 서버) C:\Program Files\Debugging Tools for Windows (x64)\srcsrv\

4. VisualSVN 설치

소스 서버에 접속해서 버전에 맞는 소스를 가져오기 위한 클라이언트를 설치한다. 클라이언트 마다 후반부에 설정이 약간 달라지며, 여기서는 VisualSVN을 기준으로 설명한다.

아래의 두 프로그램을 설치한다.

http://www.visualsvn.com/visualsvn/download/tortoisesvn/
http://www.visualsvn.com/visualsvn/download/

5. Visual Studio 설정(2005/2008)

dmp 파일을 Visual Studio에서 로드하면 dmp가 생성됐을 당시의 OS dll pdb 파일이 필요하다.

다음의 두 그림처럼 옵션을 설정하면 필요 시 자동으로 다운로드 한다.
(2. OS
심볼의 자동 다운로드 설정이 필요한 이유이다.)

6. ActivePerl 설치하기

다음 단계에서 사용 할 소스 서버 관리 프로그램인 svnindex.cmd Perl이라는 스크립트이다. 이 스크립트를 실행할 수 있도록 아래의 경로에서 프로그램을 다운 받아 설치한다.

설치 할 때 여러 가지 물어보는 데 잘 읽어보자.

http://www.activestate.com/activeperl/downloads/

7. 리부팅

설정한 path도 적용할 겸 리부팅 한 번 하자.

8. 소스 서버 접속 정보 설정

소스 서버에 접속해서 적합한 소스 파일을 얻기 위하여 소스 서버의 접속 정보를 설정해야 한다. 아래의 파일을 수정한다.(내용이 많으나 다 지우고 아래 언급한 것만 남기면 된다.)

C:\Program Files\Debugging Tools for Windows (x64)\srcsrv\srcsrv.ini

MYSERVER는 소스 서버의 주소 및 저장될 위치이다.(아래 그림 참조)
trusted commands
는 소스 서버에 접속 할 클라이언트 프로그램의 위치이다.

[variables]
MYSERVER=https://192.168.0.70:8443/svn/

[trusted commands]
svn.exe=C:\Program Files (x86)\VisualSVN\bin\svn.exe

9. 소스 서버에 솔루션의 등록

Visual Studio 2005/2008의 솔루션 탐색기에서 오른쪽 버튼을 누르면 다음과 같이 메뉴가 나타난다. Add Solution to Subversion을 실행하자

해당 솔루션의 루트 폴더를 지정하자. 뒷 부분에서 pdb파일에 소스 정보를 입력할 때 아래의 경로가 사용된다.

다음 단계에서는 대부분은 소스 서버의 관리자가 아니기 때문에 그냥 기존에 있는 걸 사용한다.

"8. 소스 서버 접속 정보 설정" 단계에서 설정한 서버의 주소를 사용한다.

Finish 버튼까지 모두 마치면 아래의 그림처럼 솔루션이 소스 서버에 등록 된다.

10. 프로젝트 빌드

이제 드디어 빌드를 할 수 있다. 빌드를 해서 exe도 만들고 pdb 파일도 생성하자.
빌드가 끝나면 소스를 소스 서버에 commit 하는 것도 잊지 말자.

11. pdb에 소스 버전 정보 삽입

svnindex를 사용해서 아래와 같이 입력하면 pdb에 소스 버전 및 위치 등을 입력한다.
/source
"9. 소스 서버에 솔루션의 등록"에서 지정한 솔루션의 루트 폴더이다
.
/symbols
는 빌드가 돼서 pdb가 존재하는 경로를 지정한다.

경로를 지정할 때에는 반드시 절대 경로를 사용한다. 상대 경로에는 몇몇 경우에 오류를 발생 시킨다고 한다.

E:\>svnindex /source="E:\Current Projects\Visual Studio 2008\Projects\TestMiniDump" /symbols="e:\Current Projects\Visual Studio 2008\Projects\TestMiniDump\Debug"

12. 소스 정보 확인

pdb에 소스 정보가 제대로 저장됐는지 확인하려면 srctool을 사용하면 된다.

E:\Current Projects\Visual Studio 2008\Projects\TestMiniDump\Debug>srctool TestMiniDump.pdb

아래 그림처럼 나온다면 성공이다.

13. 심볼 서버에 저장

이제 멀쩡한 심볼을 만들었으니 심볼 서버에 저장하면 된다. 아래의 명령은 E:\Current Projects에 있는 모든 exe/dll 등을 E:\Debugging\Symbols\Product에 저장한다는 뜻이다. 각각의 경로는 환경에 맞게 설정한다.

/t 옵션은 Title의 약자로 프로젝트 마다 설정하는 것으로 예상되나 각자 마음에 드는 것을 선택해도 상관없다. 다만 한 번 지정된 이름을 변경하면 안 된다는 것만 주의하자.

symstore add /r /f "E:\Current Projects\*.*" /s "E:\Debugging\Symbols\Products\" /t "AronStaff"

14. dmp파일의 확인

이제 모든 준비가 끝났다. dmp 파일을 더블 클릭해서 Visual Studio를 실행하고 F5를 눌러서 실행하기 버튼을 누르면 자동으로 문제가 발생한 소스의 위치와 당시의 스택 정보를 보여준다.

15. 조금 더 편하게

svnindex symsotre를 프로젝트 마다 경로를 지정하고 실행하는 것은 번거롭다.(매우 번거롭다) 그러나 Visual Studio "빌드 후 이벤트" 기능을 사용하면 보다 편하게 사용할 수 있다.

빌드 후 이벤트 항목에 아래처럼 입력하자.

call svnindex /source="$(ProjectDir)" /symbols="$(TargetDir)"
call symstore add /r /f "$(TargetDir)*.*" /s "E:\Debugging\Symbols\Products" /t "$(SolutionName)"

만약에 매 번 빌드 할 때 마다 저장되는 것이 부담스럽다면 Release 모드에서만 위의 명령을 실행하도록 설정하자. Release Debug 보다 빌드 횟수가 적어서 덜 부담스러울 것이다.

반응형
반응형

#pragma comment( linker , "/subsystem:console")

를 추가하거나

Win32 콘솔로 프로젝트를 만들거나 하면 된다

반응형
반응형

function & method 의 주석 정보


1.루틴이 무엇을 하는지

2. 메서드가 어떤 가정을 하고 있는지

3. 각각의 입력 매개 변수가 무엇을 포함해야 하는지

4. 가각의 출력 매개 변수가 성공과 실패에 대해서 무엇을 포함해야 하는지

5. 가능한 반환 값

6. 메서드에서 발생할 수 있는 예외

반응형
반응형

http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=50&MAEULNO=20&no=762711&ref=762711




VS 2005에서 "새 데이터 중단점"이 활성화가 안되길레...

어떻게 하는건가 싶어서 VS의 Help에 검색해봤더니...

 

==================================================

방법: 데이터 중단점 설정(네이티브 전용)

 

데이터 중단점을 사용하면 특정 메모리 위치에 저장된 값이 기록될 때 실행을 중단할 수 있습니다. 값을 쓰지 않고 읽을 때는 실행이 중단되지 않습니다.

 

디버깅되지 않는 프로세스에서 해당 메모리 위치에 쓰는 경우나 둘 이상의 프로세스에서 해당 메모리 위치를 공유하는 경우에는 데이터 중단점이 작동하지 않습니다. 커널 내에서 메모리 위치가 업데이트되는 경우에도 데이터 중단점이 작동하지 않습니다. 예를 들어 32비트 Windows ReadFile 함수에 메모리가 전달된 경우 커널 모드에서 메모리가 업데이트되므로 메모리에 쓸 때 디버거에서 실행이 중단되지 않습니다.

 

데이터 중단점을 설정하려면 디버거가 중단 모드여야 합니다.

 

변수의 주소는 디버깅 세션마다 달라집니다. 이러한 이유로 데이터 중단점은 각 디버깅 세션이 끝날 때 자동으로 해제됩니다.

데이터 중단점을 지역 변수에 설정한 경우에는 함수가 종료되어도 데이터 중단점이 설정된 상태로 유지됩니다. 그러나 설정된 메모리 주소의 의미는 달라집니다. 따라서 이러한 중단점의 결과는 예측할 수 없습니다. 지역 변수에 데이터 중단점을 설정한 경우에는 함수가 종료되기 전에 중단점을 제거하거나 해제하는 것이 좋습니다.

 

Visual Studio에서는 솔루션당 최대 4개의 데이터 중단점을 지원합니다.

 

메모리 변경 중단점을 설정하려면

  1. 디버그 메뉴에서 새 중단점을 선택한 다음 새 데이터 중단점을 클릭합니다.

    ? 또는 ?

    중단점 창 메뉴에서 새로 만들기를 클릭한 다음 새 데이터 중단점을 선택합니다.

    새 중단점 대화 상자가 나타납니다.

  2. 주소 상자에 메모리 주소나 메모리 주소를 계산하는 식을 입력합니다. 예를 들어, &avar 를 입력하면 avar 변수의 내용이 바뀔 때 실행이 중단됩니다.

  3. 바이트 계산 상자에 디버거에서 조사할 바이트 수를 입력합니다. 예를 들어, 4를 입력하면 디버거에서 &myFunction부터 4바이트를 조사하고 이러한 바이트의 값이 변경되면 실행을 중단합니다.

  4. 확인을 클릭합니다.

 

=======================================================

 

라고 나오네요. ;;;; ㅎㅎㅎ

 

그런데 여기서.... "네이티브 전용"이라는 말의 의미를 모르겠어서... 이렇게 질문을 드립니다.

객체의 멤버 변수들을 모두 NULL값으로 초기화 해서 생성했는데, 막상 사용할때 보니 쓰레기 값이 들어가있는 멤버들이 몇개 있어서... 이러고 있답니다. 에휴...

 

멋진분의 답변을 기다리고 있겠습니다.감사합니다.

반응형
반응형

문자열변환2

송정헌 2010-01-18 11:47:30 주소복사
조회 28 스크랩 0

char *, wchar_t *, _bstr_t, CComBSTR, CString, basic_string, System.String 변환

char *

char *orig = "Hello, World!";

size_t origsize = strlen(orig) + 1; // wchar_t *

const size_t newsize = 100;

size_t convertedChars = 0;

wchar_t wcstring[newsize];

mbstowcs_s(&convertedChars, wcstring, origsize, orig, _TRUNCATE);

wcscat_s(wcstring, L" (wchar_t *)");

_bstr_t bstrt(orig); // _bstr_t

bstr += " (_bstr_t)";

CComBSTR ccombstr(orig); // CComBSTR

if(ccombstr.Append(L"(CComBSTR)") == S_OK) CW2A printstr(ccombstr);

CString cstring(orig); // CString

cstring += " (CString)";

string basicstring(orig); // basic_string

basicstring += " (basic_string)";

String ^systemstring = gcnew String(orig); // System.String

systemstring += " (System::String)";

delete systemstring;

wchar_t *

wchar_t *orig = L"Hello, World!";

size_t origsize = wcslen(orig) + 1; // char *

const size_t newsize = 100;

size_t convertedChars = 0;

char nstring[newsize];

wcstombs_s(&convertedChars, nstring, origsize, orig, _TRUNCATE);

strcat_s(nstring, " (char *)");

_bstr_t bstrt(orig); // _bstr_t

bstrt += " (_bstr_t)";

CComBSTR ccombstr(orig); // CComBSTR

if(ccombstr.Append(L" (CComBSTR)") == S_OK) CW2A printstr(ccombstr);

CString cstring(orig); // CString

cstring += " (CString)";

wstring basicstring(orig); // basic_string

basicstring += L" (basic_string)";

String ^systemstring = gcnew String(orig); // System.String

systemstring += " (System::String)";

delete systemstring;

_bstr_t

BSTR을 캡슐화하는 COM 지원 클래스 (comutil.h, comsuppw.lib 또는 comsuppwd.lib)

_bstr_t orig("Hello, World!");

const size_t newsize = 100; // char *

char nstring[newsize];

strcpy_s(nstring, (char *)orig);

strcat_s(nstring, " (char *)");

wchar_t wcstring[newsize]; // wchar_t *

wcscpy_s(wcstring, (wchar_t *)orig);

wcscat_s(wcstring, L" (wchar_t *)");

CComBSTR ccombstr((char *)orig); // CComBSTR

if(ccombstr.Append(L" (CComBSTR)") == S_OK) CW2A printstr(ccombstr);

CString cstring((char *)orig); // CString

cstring += " (CString)";

string basicstring((char *)orig); // basic_string

basicstring += " (basic_string)";

String ^systemstring = gcnew String((char *)orig); // System.String

systemstring += " (System::String)";

delete systemstring;

CComBSTR ATL의 BSTR wrapper 클래스 (atlbase.h)

CComBSTR orig("Hello, World!");

CW2A printstr(orig);

const size_t newsize = 100; // char *

char nstring[newsize];

CW2A tmpstr1(orig);

strcpy_s(nstring, tmpstr1);

strcat_s(nstring, " (char *)");

wchar_t wcstring[newsize]; // wchar_t *

wcscpy_s(wcstring, orig);

wcscat_s(wcstring, L" (wchar_t *)");

_bstr_t bstrt(orig); // _bstr_t

bstrt += " (_bstr_t)";

CString cstring(orig); // CString

cstring += " (CString)";

wstring basicstring(orig); // basic_string

basicstring += L" (basic_string)";

String ^systemstring = gcnew String(orig); // System.String

systemstring += " (System::String)";

delete systemstring;

CString ATL/MFC의 템플릿 클래스인 CStringT의 기본 구현 클래스.

CString orig("Hello, World!");

const size_t newsize = 100; // char *

char nstring[newsize];

strcpy_s(nstring, orig);

strcat_s(nstring, " (char *)");

// wchar_t * (이 작업을 하려면 먼저 char *로 바꿔야 한다)

size_t origsize = strlen(orig) + 1;

size_t convertedChars = 0;

wchar_t wcstring[newsize];

mbstowcs_s(&convertedChars, wcstring, origsize, orig, _TRUNCATE);

wcscat_s(wcstring, L" (wchar_t *)");

_bstr_t bstrt(orig); // _bstr_t

bstrt += " (_bstr_t)";

CComBSTR ccombstr(orig); // CComBSTR

if(ccombstr.Append(L" (CComBSTR)") == S_OK) CW2A printstr(ccombstr);

string basicstring(orig); // basic_string

basicstring += " (basic_string)";

String ^systemstring = gcnew String(orig); // System.String

systemstring += " (System::String)";

delete systemstring;

basic_string STL 클래스 (<string>)

string orig("Hello, World!");

const size_t newsize = 100; // char *

char nstring[newsize];

strcpy_s(nstring, orig.c_str());

strcat_s(nstring, " (char *)");

// wchar_t * (이 작업을 하려면 먼저 char *로 바꿔야 한다)

size_t origsize = strlen(orig.c_str()) + 1;

size_t convertedChars = 0;

wchar_t wcstring[newsize];

mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);

wcscat_s(wcstring, L" (wchar_t *)");

_bstr_t bstrt(orig.c_str()); // _bstr_t

bstrt += "(_bstr_t)";

CComBSTR ccombstr(orig.c_str()); // CComBSTR

if(ccombstr.Append(L" (CComBSTR)") == S_OK) CW2A printstr(ccombstr);

Cstring cstring(orig.c_str()); // CString

cstring += " (CString)";

String ^systemstring = gcnew String(orig.c_str()); // System.String

systemstring += " (System::String)";

delete systemstring;

System.String .NET 프레임워크 클래스 (mscorlib)

String ^orig = gcnew String("Hello, World!");

pin_ptr<const wchar_t> wch = PtrToStringChars(orig);

size_t origsize = wcslen(wch) + 1; // char *

const size_t newsize = 100;

size_t convertedChars = 0;

char nstring[newsize];

wcstombs_s(&convertedChars, nstring, origsize, wch, _TRUNCATE);

strcat_s(nstring, " (char *)");

wchar_t wcstring[newsize]; // wchar_t *

wcscpy_s(wcstring, wch);

wcscat_s(wcstring, L" (wchar_t *)");

_bstr_t bstrt(wch); // _bstr_t

bstrt += " (_bstr_t)";

CComBSTR ccombstr(wch); // CComBSTR

if(ccombstr.Append(L" (CComBSTR)") == S_OK) CW2A printstr(ccombstr);

CString cstring(wch); // CString

cstring += " (CString)";

wstring basicstring(wch); // basic_string

basicstring += L" (basic_string)";

delete orig;

반응형

+ Recent posts