VC++환경에서 메모리릭을 찾기 위한 방법은 디버그 모드에서 CRT(C runtime library)디버그 함수를 사용


1. 밑에 선언하는 방법


- _CrtDumpMemoryLeaks()함수로 메모리릭 찾기

  #define CRTDBG_MAP_ALLOC

  #include <stdlib.h>

  #include <crtdbg.h>

  //위의 순서를 반드시 지켜야 함


  void memleak()
  {
      // 메모리가 누수가 일어나는 부분

  }                                                    


  void main()
  {
   memleak();

  _CrtDumpMemoryLeaks();
  }

_CrtDumpMemoryLeaks() 함수를 사용하여 메모리릭을 찾는 방법을 사용시는 반드시 메모리릭이 발생된 이후 시점에서 이 함수를 호출해야만 누수된 메모리 블록 정보를 확인할 수 있다.


2. 위에 선언하는 방법

- _CrtSetDbgFlag()함수로 메모리릭 찾기==> 프로그램 시작부분에 함수 호출

  _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); 호출


#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <string.h>
#include <crtdbg.h>

void memleak()
{
  ... // (메모리 누수가 일어나는 부분)

}

void main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
memleak();
}


[옵션들]

_CRTDBG_ALLOC_MEM_DF - 메모리 할당이 일어나는 경우 추적하게 해줍니다.

_CRTDBG_LEAK_CHECK_DF - 종료시에 _CrtDumpMemoryLeaks()를 호출하여 메모리 누수 정보를 표시해 줍니다.

_CRTDBG_DELAY_FREE_MEM_DF - 실행중간에 메모리가 해제 된다고 하더라도 실제로 해제를 실행하지 않고 종료 시 해제를 하게 합니다.

_CRTDBG_CHECK_ALWAYS_DF - 모든 할당 및 할당 취소에서 _CrtcheckMemory를 호출하여 실행속도는 지연되지만 오류를 신속하게 찾아냅니다.

_CRTDBG_CHECK_CRT_DF - CRT내부도 메모리 탐지에 포함 시킵니다.


3. New메모리에 CRT기능 넣기

위에 1,2번 기준으로 디버깅을 돌려보면은 메모리 누수 정보는 나오지만 new 메모리 할당시에는

정확한 정보가 나오지 않는다

아래와 같이 고치면 정확한 정보가 뜰 것이다.


#include <stdio.h>
#include <string.h>
#include <crtdbg.h>

//디버그용  new
#ifdef _DEBUG
#define new new(_CLIENT_BLOCK, __FILE__, __LINE__)
#endif

int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);


...


return 0;
}


[참고]

기본적으로 MFC에서는 위 코드를 활용할 필요가 없다.

왜냐면 메모리 누수 관련 코드가 만들자마자 자동 삽입되기때문이다.


출처 : 네이버 게임 프로그래밍 카페

Posted by Gungume
,

1. 모든 소스의 선두에 아래 순서대로 입력한다.

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)


- 순서가 다르면 안됨

- stdafx.h(미리 컴파일된 해더)에 넣어도 된다.



2. Main()함수 - 맨 처음 시작하는 함수

첫번째 라인에 아래와 같이 적는다.

_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);



3. VS에서 디버그 모드로 시작(F5)하고, 스스로 종료해야 한다.

(Shift + F5를 하지 말라는 의미임)



4. 기타

- 직접 테스트 해 본 결과로는 Malloc도 가능하다.

 (#define new 없으면 new만 된다..-_-a 잘 이해 안됨)

- CRT로는 전체 CallStack을 찍어주지 않고

  최종적으로 new를 사용한 곳을 찝어주는 것 같다.

  만약 이미 소스에서 new를 다르게 만들어 사용한다면 역시나 찾을 수 없게 될 듯.




[예제]

#include "stdafx.h" //여기엔 이 두가지만 있다.

//#include <iostream>
//#include <tchar.h>

//만약 아래의 내용을 iostream보다 먼저 쓰는 경우 Error가 난다.


#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)


int _tmain(int argc, _TCHAR* argv[])
{
       _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
       char* pNew = NULL;
       pNew = new char;


       char* pMalloc = NULL;
       pMalloc = (char*)malloc( sizeof(char) * 10 );


       char* pAA = NULL;
       pAA = new char[100];
       delete [] pAA;


       return 0;
}


[잘 된 결과]

- 아래처럼 실제로 사용한 파일명과 할당한 라인 수가 나와야 제대로 된 것

Detected memory leaks!
Dumping objects ->
d:\study myself\디버깅\crtmemoryleak\crtmemoryleak.cpp(30) : {44} normal block at 0x00372D80, 10 bytes long.
Data: <          > CD CD CD CD CD CD CD CD CD CD
d:\study myself\디버깅\crtmemoryleak\crtmemoryleak.cpp(24) : {43} normal block at 0x00372D40, 1 bytes long.
Data: < > CD
Object dump complete.
'[840] CRTMemoryLeak.exe: 네이티브' 프로그램이 0 (0x0) 코드에서 끝났습니다.


[잘못된 결과]

- 순서가 잘못되거나 하면 crtdbg.h파일의 라인수가 나온다.

Detected memory leaks!
Dumping objects ->
c:\program files\microsoft visual studio .net 2003\vc7\include\crtdbg.h(689) : {43} normal block at 0x00372D40, 1 bytes long.
Data: < > CD
Object dump complete.


출처 : 네이버 블로그였는데 까먹음;;;

Posted by Gungume
,

해쉬...

Language/C/C++ 2006. 12. 1. 00:56

Hash.exe




학교과제로 했던 해쉬를 이용한 간단한 주소록이다...(그냥 이름, 전화번호 정보 추가, 삭제, 검색정도...)

해싱함수는 제산 잔여 해싱 기법을 사용했는데 제대로 한건지도 모르겠다;;;

해싱함수에 쓰이는 Key값은 MultiByteToWideChar() 함수를 이용했다...

MultiByteToWideChar()함수로 문자열(이름)을 유니코드로 변경하는데 사용했다...

한글기준 이름 3자를 입력받는다는 가정으로...이름 한자씩을 유니코드로 변환하고 그 값을 모두 합해서 버킷수로 나머지 연산을 해서 버킷주소를 생성하는식으로 코딩했다...

이름이 3자 이하일때가 문제가 되지만...이름에서 성 부분만 키값으로 사용하거나 하면 너무 한쪽으로 몰려서 그냥 저렇게 해버렸다 ㅡㅡ

data.txt 파일에 이름을 입력해 놓으면 파일입력으로 데이터를 입력받을 수 있다...(이때 전화번호는 랜덤생성...)

아래 스샷은 입력된 데이터를 파일출력했을때 결과이다...

해쉬 프로그램


해쉬 결과

(사용언어 : C++)


Posted by Gungume
,



키보드에는 방향키가 있습니다.(→←↑↓) 이것을 코드값을 이용해서 입력 받는 방법을 알아보겠습니다.

방향키의 코드값이 아스키코드에 있다면 getch()함수를 이용해서 쉽게 해결할 수 있겠지만, 아스키값에는 방향키가 없습니다. 그래서 다른 것을을 이용해서 방향키의 코드값을 입력 받아야합니다.

http://www.lookuptables.com/ ->"Scan Codes & EBCDIC" -> "IBM Scan Codes"를 이용합니다...

그곳에서 보면 10진수 값만을 따졌을 경우에 아래와 같이 각각의 코드값이 나옵니다.

UP = (00, 72), LEFT = (00, 75), RIGHT = (00, 77), DOWN = (00, 80)

즉, 방향키는 2개의 값을 가지고 있습니다. 예를 들어 다시 설명하면 "UP" 방향키를 눌렀을때 발생하는 코드값은 처음에 00을 리턴하고 그 다음에는 72를 리턴합니다.

리턴값이 2개이니까 간단히 설명하면 두번 입력을 받아주면 됩니다.

하나의 예를 들어보자면 char형으로 ch라는 변수를 선언한 후에 "ch=getch();"라는 명령어가 있다면 커서가 깜박일때 "A"를 눌렀다면 엔터를 칠 필요도 없이 "A"의 값이 ch변수에 들어갑니다.

그럼 원래의 목적인 방향키로 가봅니다. 위에서 말씀드렸듯이 방향키는 값을 2개 리턴하므로 getch()함수를 두번 쓰면 됩니다.

int형으로 cursor이라는 변수를 선언했다고 가정후에 아래와 같이 사용하면 cursor의 최종값은 방향키의 2번째 리턴값이 들어갑니다. 예를 들어 "UP" 방향키를 눌렀다면 cursor의 최종값은 72가 되겠죠...

int cursor=getch();
if (cursor==0 || cursor==0x00)
    cursor=getch();

프로그램이 실행되다가 소스의 첫번째 줄을 만나면 사용자에게 뭔가를 입력하라고 커서가 깜박이겠죠...

이때 방향키가 아닌 그냥 알파벳이나 숫자를 넣으면 해당되는 아스키값이 들어가겠죠...

그러나 방향키를 입력하면 리턴값이 2개니까 첫번째 줄을 실행하면서 첫번째 리턴값인 "00"을 cursor 변수에 넣습니다. 그리고 if문을 실행하면서 cursor값이 0인지를 검사합니다.

"00==0" 즉, 조건이 참이되므로 세번째 줄에 있는 getch()함수를 실행하겠죠...

세번째 줄에 있는 getch()문은 따로 입력 받는 것이 아니고 첫번째 줄에서 입력했던 방향키 값중에 두번째 리턴값을 자동으로 넘겨받게됩니다...

그래서 최종값이 "UP"키를 눌렀다는 가정하에 72가 되는것입니다....

이렇게 입력을 받았다면 이후에는 각각의 경우에 할일을 만들어 주면 되겠죠...

그리고 조건문중에 0x00부분도 있는데 이것은 0의 16진수입니다...저런식으로 같이 써주면 좋겠죠...

또한 저는 vc++7.0이라서 그냥 저렇게 했을때 작동을 했는데...어떤 사람은 vc++에서 "00"이 리턴이 안되고 "?"가 리턴이 된다는 사람도 있더군요....이 경우에는 조건문에 ?를 추가로 입력하면 됩니다.

첨부 파일은 위의 내용을 적용한 예제 프로그램입니다.

프로그램을 실행후에 방향키를 움직이면 방향키를 누른데로 *표가 움직입니다.

P.S *표의 위치를 표시하기 위해 터보C에서 쓰이는 gotoxy() 함수사용...vc++등의 개발툴에는 없는 함수이므로 www.winapi.co.kr에서 헤더파일 구해서 사용함...

Posted by Gungume
,

D-day 계산기

Language/C/C++ 2006. 4. 26. 23:32

D-day.exe



D-day 계산기


간단하게 만들어본 D-day 계산기...

입력 형식 : YYYY.MM.DD

(사용언어 : C++)

Posted by Gungume
,

client.exe




고객관리 프로그램 입력

고객관리 프로그램 출력


학교 과제로 했던 연결리스트를 이용한 고객관리 프로그램....

연결리스트 학습을 목적으로 제작한 프로그램이라서 별다른 기능은 없음 ㅡㅡ;

(사용언어 : C++)


Posted by Gungume
,


주소록 프로그램

이중연결리스트를 이용한 주소록 프로그램....

입력은 간단하게 이름, 전화번호, 주소만 받음...

입출력, 검색, 수정, 삭 제, 파일 출력 등의 기능이 있음...

나름데로는 이중연결리스트 부분 소스가 잘되어 있는것 같음...

(사용언어 : C++)
Posted by Gungume
,

car.exe



정비소 관리 프로그램 차량 등록

정비소 관리 프로그램 수리상태 출력


과제로 간단하게 했던 정비소 관리 프로그램.....

문제 파악을 제대로 못해서 문제의 의미데로 코딩한 것인지 알수 없음... ㅡㅡ;

(사용언어 : C++)


Posted by Gungume
,


판매 실적표 처리 프로그램 입력
판매 실적표 처리 프로그램 출력

학교 스터디모임에서 과제로 했던 프로그램...

과제 받았을 당시에 수준에 비해 문제가 어려워서 대충대충 짰음 ㅡㅡ;

(사용언어 : C++)
Posted by Gungume
,



성적 계산 프로그램 입력
성적 계산 프로그램 출력

프로그램 실행시 구조체를 동적으로 생성해서 처리할 인원수를 결정...

단순히 국어, 영어, 수학 점수만을 입력 받아서 총점과 평균 계산...

정렬, 검색, 삭제, 파일 출력 등의 기능 구현됨...

(사용언어 : C++)

Posted by Gungume
,