strcpy_s의 두번째 인자에 _TRUNCATE가 들어가면 어떤 현상이 일어날까?

_TRUNCATE의 값은 unsigned int의 최대값 즉 약42억(정확히 42 9496 7295) - 4G - 값이므로 무한대라고 할수 있다.

strcpy_s( a, _TRUNCATE, b) --> strcpy_s( a, 42억, b)..

결론은 strcpy_s를 strcpy로 바꿔버리는 현상(첫번째 인자 버퍼는 보호하지 않음)이 일어난다.
예제 소스
#include <string.h>
#include <iostream>

using namespace std;

int main( int, char *[] )
{
    char    c[16];
    char    a[4];
    
    const char *  b = "012345678901234567890";

    cout << "\n====== memset ======\n";

    memset( a, 'A', sizeof(a) );
    memset( c, 'C', sizeof(c) );

    cout.write( a, _countof(a) ) << endl; // AAAA 출력
    cout.write( c, _countof(c) ) << endl; // CCCCCCCCCCCCCCCC 출력

    /* 예외 발생
    strcpy_s( a, _countof(a), b );
    cout.write( a, _countof(a) ) << endl;
    cout.write( c, _countof(c) ) << endl;
    */ 
    
    cout << "\n====== strcpy_s ======\n";
    strcpy_s( a, _TRUNCATE, b );
    cout.write( a, _countof(a) ) << endl; // 0123 출력
    cout.write( c, _countof(c) ) << endl; // buffer Overflow

    return 0;
}


출력

====== memset ======
AAAA
CCCCCCCCCCCCCCCC

====== strcpy_s ======
0123
234567890    -----> over flow

뱀다리) _TRUNCATE 의 값은 #define _TRUNCATE ((size_t)-1) 이다
그리고 size_t는 unsigned int 형이므로 _TRUNCATE 값은 unsigned int 의 최대값 대략 42억(정확히 42 9496 7295)의 값을 가집니다.
Visual C++에서 작업 하였다.

출력
CPU Usage : 57.8125%
CPU Usage : 40.625%
CPU Usage : 28.125%
CPU Usage : 29.6875%
CPU Usage : 18.1818%
CPU Usage : 21.875%
CPU Usage : 4.6875%
CPU Usage : 1.5625%


소스
#pragma comment(lib, "pdh.lib")

#include <windows.h>
#include <pdh.h>
#include <pdhmsg.h>
#include <iostream>

using namespace std;

class CpuUsage
{
private:
        PDH_HQUERY              m_hQuery;
        PDH_HCOUNTER    m_hCounter;

public:
        CpuUsage()      :       m_hQuery( 0 ), m_hCounter( 0 )  {}
        ~CpuUsage()             {       destroy();      }

        bool    init()
        {
                PDH_STATUS      status = PdhOpenQuery (0, 0, &m_hQuery);

                if( status != ERROR_SUCCESS )
                        return false;

                status = PdhAddCounter( m_hQuery, "\\Processor(_TOTAL)\\% Processor Time", 0, &m_hCounter );

                if( status != ERROR_SUCCESS )
                        return false;

                status = PdhCollectQueryData( m_hQuery );

                if( status != ERROR_SUCCESS )
                {
                        return false;
                }

                return true;
        }

        void    destroy()
        {
                if( m_hQuery )
                        PdhCloseQuery( m_hQuery );
                m_hQuery = 0;
        }

        bool    getCpuUsage( double * val )
        {
                PDH_STATUS      status = PdhCollectQueryData( m_hQuery );

                if( status != ERROR_SUCCESS )
                        return false;

                PDH_FMT_COUNTERVALUE    value;

                status = PdhGetFormattedCounterValue( m_hCounter, PDH_FMT_DOUBLE,       0, &value);

                if (status != ERROR_SUCCESS)
                        return false;
                *val = value.doubleValue;
                return true;
        }

};


int main( int argc, char * argv[] )
{
        CpuUsage        cpuUsage;
        if( cpuUsage.init() == false )
                return 1;

        while( true )
        {
                double  val = 0.0;
                if( cpuUsage.getCpuUsage( &val ) )
                        cout << "CPU Usage : " << val << "%\n";
                Sleep( 500 );
        }
        cout << "\t\thttp://fehead.tistory.com\n";

        return 0;
}


출력
 
Total : 2096236 free : 1242116


소스
#include <Windows.h>
#include <iostream>

struct ST_MemLog
{
        ULONG   totalMem;
        ULONG   freeMem;
};


bool    getMemLog( ST_MemLog * pMemLog )
{
        static const long       KBYTE = 1024;

        MEMORYSTATUSEX statex;

        statex.dwLength = sizeof (statex);

        if( GlobalMemoryStatusEx( &statex ) == FALSE )
                return false;

        // total Kbytes of physical memory
        pMemLog->totalMem = static_cast<ULONG>( statex.ullTotalPhys / KBYTE );

        // free Kbytes of physical memory.
        pMemLog->freeMem = static_cast<ULONG>( statex.ullAvailPhys / KBYTE );

        return true;
}

int main( int argc, char * argv[] )
{
        ST_MemLog       memLog;

        if( getMemLog( &memLog ) ) {
                cout << "Total : " << memLog.totalMem <<
                        "\tfree : " << memLog.freeMem << endl;
        }
        cout << "\t\thttp://fehead.tistory.com\n";

        return 0;
}


소스예제
#include <windows.h>
#include <iostream>

using namespace std;

int main( int, char *[] )
{
        const int arr[] = {100, 200, 300, 400, 500};

        cout << "_countof(arr)              : " << _countof(arr) << endl;
        cout << "sizeof(arr)                : " << sizeof(arr) << endl;
        cout << "sizeof(arr)/sizeof(arr[0]) : " << sizeof(arr) / sizeof(arr[0]) << endl;

        return 0;
}

결과
_countof(arr)              : 5
sizeof(arr)                : 20
sizeof(arr)/sizeof(arr[0]) : 5


소스를 참고 하시라^^

소스 세이프 2005에서 쓰기 모드로 코딩하기 무척이나 힘듭니다.

쓰기모드로 컴파일도 제대로 못하게 해놔서 참 힘들더군요.

파일 하나를 다른사람이 체크아웃하고 사용중이면 거의 아무것도 못하게 되어있습니다.


그래서 열심히 구글링 해봤으나 못 찾고 결국 하나하나 해서 결국 찾았습니다.


Visual C++ 2008 옵션창에 들어가서



  • 툴--> 옵션

    • 소스제어(Source Control) --> 환경(Environment) 중

      • On Edit --> 단독 체크 아웃 확인(Prompt for exclusive checkouts)

으로 설정하시고 visual C++ 재시작하시고 쓰기 모드로 작업하시면 되겠습니다.


기존에 쓰기 모드로 한 작업들은 위설정으로 바꾸고 GetLast후 다시 작업하셔야 합니다.

요즘 회사에서 visual C++ 2003에서 Visual C++ 2008로 컨버팅 작업을 하다가

독자적으로 구현한 hashmapList 라는것이 있는데 이중 iterator 를 구현한것에서 컴파일이 되지 않는 현상이 발생하였다.

참 애매한 컴파일 문제 였는데.

iterator_category 가 구현되어 있지 않다고 에러가 났는데 도무지 모르겠더군요.

소스를 추척하다보니 iterator_traits 이 구현되어 있지 않다는걸 알아 냈는데.

전에 내용을 이해 하지 못한체 읽은 The C++ Programing Language 책에 특성(trait)가 생각나서 봐 보았는데.

이게 바로 에러가 나는 원인이었습니다.

이제서야 이 책의 필요성을 느꼈습니다.

전에는 별 필요성을 못느끼고 의무감에서 봤는데.. 이제는 필요성이 느껴져서 읽을것 같습니다.

책은 필요성은 있어야 재미있게 읽을수 있을것 같습니다.^^
C, C++ 에서 Header 파일 2개간 define이 선언된것을 비교하는 툴을 만들어 보았다.

사용법은

defineCompare firstheader.h secondheader.h
이다

목록이 나오는것은.. header1.h 에는 없지만 header2.h에는 있는 목록이 나오며

defineCompare firstheader.h secondheader.h

defineCompare secondheader.h firstheader.h

결과는 틀리게 나온다.

소스를 첨부한다.



허접소스라 지원하지 않는 명령어가 있고 2중 조건문 등이 있으면 안된다.

인식가능한 키워드는
#ifdef
#else
#endif
#ifndef
#define
#undef
//
/*
*/

이며 #ifdef 등의 2중 조건문이 있으면 안된다.


아직 서두만 보고 읽다..

이책을 산지 한 3, 4년은 지난것 같다.

처음봤을때 왜 이따위야 하는 생각을 했다.

너무 복잡했다. 지루했다...

그런데 이번에 보니.. 꽤 재미있게 보였다.- 아직 85페이지정도 보고있다.

한가지 확실한것은 처음 보았을때와 이책을 지금 보고 있을때 차이점이 있다.

1. 네트워크 프로그래밍을 좀더 알게 된 상태였다.
2. 디자인 패턴을 알고 있다.

이 두가지다..

이책을 읽고 흥미를 느끼려면 최소한 아래의 스킬은 필수다.

없다면 보지마라. ACE에 분명히 실망할테니까

1. C++ 프로그램 실력 : Efective C++, Efective STL 등을 이해하는데 문제 없는자.

2. 네트워크 프로그래밍 실력 : 최소 IOCP를 재대로 이해하고 있다.

3. 디자인 패턴을 아는자 : Head First 디자인 패턴 책을 최소 2번 이상은 봤으며 거의 이해한다.
   혹은 이에 준하는 내용을 알고 있다.

http://msdn.microsoft.com/en-us/library/c785s0kz(VS.80).aspx

변수값 출력
> ? var1

변수값 출력시 ? 붙이기 귀찮을때
> immed
명령어를 치고 변수값을 직접 넣어 값을 출력한다.

command window로 복귀
>cmd

header 파일에 아래의 내용을 넣고 컴파일한다.

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

참고 링크
http://kldp.org/node/105369


+ Recent posts