C++ 반전 연산자~와 논리 연산자 !의 차이

Skills/Programming 2014. 12. 16. 14:51

case CMD_TELEOPERATION:    

{

bETRI_Tele = !bETRI_Tele;

cout<<"bETRI_Tele : "<<bETRI_Tele<<endl;

}

MFC 다이얼로그를 통해 버튼을 누르면 위의 코드에 들어가게 해 두었다.

그런데 이상한 점 발견! 


bETRI_Tele = ~bETRI_Tele; 로 할 때에는 cout이 계속 1의 값을 반환한다는 것이다!

그러나 bETRI_Tele = !bETRI_Tele; 로 할 때에는 버튼을 누를 때마다 0과 1의 값이 반복되면서 제대로 잘 나온다.


일단, 그 원인은 ~가 bit 연산자라는 것에 있을 것으로 판단되고 boolean이 bit로 보았을 때에는 단순한 1과 0 이 아닐 것이라는 추측이 된다.

설정

트랙백

댓글

공유 메모리를 이용한 IPC

Skills/Programming 2014. 12. 15. 16:49

IPC (Inter Process Communication)란, 프로세스 간에 정보를 주고받을 수 있도록 하는 통신 기법

32bit 시스템에서는 각 프로세스에 제공되는 연속적인 4GB의 가상 메모리를 사용하는데, 가상 메모리 중 절반은 사용자 모드(스택, 힙)에 사용하고 나머지 절반은 커널 모드(운영체제가 관리)에 사용한다.

공유 메모리를 이용한 IPC는 커널 모드의 메모리 영역을 활용하여 프로세스 간에 서로 통신하는 기법임.


* Ref  (or copied from)

[1] 열혈강의 VISUAL C++ 2008 MFC 윈도우 프로그래밍, 최호성, 2009.

설정

트랙백

댓글

MFC dialog에서 콘솔(console)로 디버깅하기

Skills/Programming 2014. 12. 15. 15:09

MFC 다이얼로그를 이용하다 보면, 콘솔 응용프로그램을 코딩할 때처럼 printf 나 cout 같은 것으로 디버깅하고 싶을 때가 있다.. 그럴  떄 아래와 같은 방법으로 해결할 수 있다.


방법 1
App의 InitInstance에서 AllocConsole()을 호출한다.
디버그 모드에서만 동작할 것이므로 간단히 다음과 같이 할 수 있겠다.

#ifdef _DEBUG
    if( !AllocConsole() )
    {
        AfxMessage(_T("Failed to create the console!"), MB_ICONEXCLAMATION);
    }
#endif

해제하기 위해서는 ExitInstance에서 FreeColsole()을 호출한다.
이전과 마찬가지로 다음과 같이 쓰면 된다.

#ifdef _DEBUG
    if( !FreeConsole() )
    {
        AfxMessage(_T("Failed to free the console!"), MB_ICONEXCLAMATION);
    }
#endif

방법 2
stdafx.h에서 다음과 같이 입력한다.

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


출력은 일반적인 콘솔 프로그램과 같이 cout이나 printf 등을 사용하면 된다.

설정

트랙백

댓글

[C/C++] double 형 데이터에 분수 넣기

Skills/Programming 2014. 12. 9. 17:19

함수를 정의할 때, parameter로 double 형 데이터를 활용하게 되는 경우가 종종 있다.

그런데 이 때, 함수를 사용하는 쪽에서 double 형 데이터에 소수점 값을 넣게되는 경우가 있는데

소수점 값을 직접 입력하지 않고 분수로 값을 입력할 때 실수가 가장 많다.

예를 들면 아래와 같은 코드를 생각해 보자.


#include <stdio.h>

 void test(double num)

{       

     printf("%lf \n", num);

}

 

int main()

{

        test(0.001);

        test(1/1000);

              

        return 1;

}


이 때, 1/1000 을 넣으면 값은 0 이 나온다.

분수의 형태로 넣고 싶다면 1.0/1000.0 처럼 double 형으로 인식할 수 있도록 해 주어야 한다.

(혹은 casting을 해 주어도 괜찮다.)

설정

트랙백

댓글

첫째 예외가 있습니다. 0xC0000005: 0x00000018 위치를 읽는 동안 액세스 위반이 발생했습니다.

Skills/Programming 2014. 11. 12. 15:06

프로그래밍을 하다보면 가장 자주 만나는 에러 메시지 중의 하나이다..

첫째 예외가 있습니다. 0xC0000005: 0x00000018 위치를 읽는 동안 액세스 위반이 발생했습니다.


가장 흔히 하는 실수로는 아직 할당하지 않은 메모리에 접근하는 경우에 발생한다.

예를 들어 A 라는 class를 정의해 두고서 A의 포인터 객체를 생성한 후 메모리를 할당하지 않은 상태에서 

포인터 객체의 멤버에 접근을 하는 경우에 발생하는 경우가 가장 흔하다.


A *a;

a ->멤버함수 or 멤버변수 사용 ;

...첫째 예외가 있습니다. 0xC0000005: 0x00000018 위치를 읽는 동안 액세스 위반이 발생했습니다.


a라는 포인터 객체를 생성했다면 new 연산자를 통해 메모리를 할당해 주어야 한다. 

아래와 같은 패턴으로 사용하면 에러 메시지는 발생하지 않을 것이다.


A *a;

a = new A;

a ->멤버함수 or 멤버변수 사용 ;

delete a;  //이 때 가장 중요한 메모리 해제는 잊으면 안된다.


그런데, 내가 이번에 경험한 경우는 Roboticslab이라는 시뮬레이션 프로그램을 짜다가 발생한 문제이다.

xdl 파일을 통해 control algorithm이 작성되어있는 dll을 하나의 응용프로그램에서 공유하면서 발생한 문제인 것으로 보여진다.

이유는 모르겠지만 ,TeachingSW라는 클래스의 포인터 객체를 생성하여 메모리를 할당한 후에 멤버 변수에 접근을 했음에도 위와 같은 엑세스 에러가 발생했다.

그래서 직접 해당 에러가 발생하는 변수만 memset을 통해 메모리를 설정해 주니 해당 에러가 없어지는 것아닌가.. 

정확한 원인은 파악하지 못했지만, 임시 방편으로 발견한 해결책이라도 기억해 두면 좋을 것 같다.


구현 예..


  ///////////////////////////////////

//// TeachingSW 관련 변수 초기화

if (StringComp(identifier, id_L) == 1){

T_HML = new TeachingSW_HM;

memset(&T_HML->home_q, 0, sizeof(T_HML->home_q)); //// 정말 이상한 점... home_q만 건들면 엑세스 에러가 발생해서 멤셋을 따로 해준다..

T_HML->home_q.resize(7); //// 정말 이상한 점인데... home_q만 건들면 엑세스 에러가 발생해서 멤셋을 따로 해준다..

T_HML->event_q.resize(7);

T_HML->cur_q.resize(7);

T_HML->des_q.resize(7);

}

else if (StringComp(identifier, id_R) == 1){

T_HMR = new TeachingSW_HM;

memset(&T_HMR->home_q, 0, sizeof(T_HMR->home_q)); //// 정말 이상한 점... home_q만 건들면 엑세스 에러가 발생해서 멤셋을 따로 해준다..

T_HMR->home_q.resize(7); //// 정말 이상한 점인데... home_q만 건들면 엑세스 에러가 발생해서 멤셋을 따로 해준다..

T_HMR->event_q.resize(7);

T_HMR->cur_q.resize(7);

T_HMR->des_q.resize(7);

}







설정

트랙백

댓글

클래스 객체 생성 방법에 관하여.. (new 사용에 관하여)

Skills/Programming 2014. 11. 12. 14:57

클래스의 객체를 생성할 때 new 를 사용하는 이유가 무엇일까.

헤더 파일에 new를 사용하지 않은채 사용하면 안되는 것일까?

예를 들어, 

TeachingSW_HM T_HM;


그런데 이렇게 했을 때에는 메모리가 스택영역에 올라가게 된다고 한다. 

그래서 변수가 올라가는 영역을 벗어날 경우에 메모리가 자동으로 해제된다. 


그러나 new를 활용하여 메모리를 동적으로 할당할 경우

예를 들어,

TeachingSW *T_HM;

T_HM = new TeachingSW();


메모리는 힙 영역으로 올라가게 되어 delete를 이용해서 직접 해제하기 전까지는 메모리에 유지가 된다.


설정

트랙백

댓글