shared_ptr과 포인터 변환에 대한 질문2
글쓴이: telepathy070 / 작성시간: 화, 2016/01/05 - 6:06오후
class StringContainer { public: StringContainer(); char tmp_array[32]; }; StringContainer::StringContainer() { memset(tmp_array, 0, sizeof(tmp_array)); strcpy(tmp_array, "dream comes true!!!"); } long long extern_raw_cstring_address; std::shared_ptr<StringContainer> ext_cr; function A() { std::shared_ptr<StringContainer> cr = shared_ptr<StringContainer>(new StringContainer()); extern_raw_cstring_address = (long long)(reinterpret_cast<void * >(&cr)); //shared_ptr 주소 출력 ext_cr = cr; //외부 변수에 대입하여 shared_ptr 함수를 벗어나도 삭제되지 않게 막기 } function B() { StringContainer* ext_data = ext_cr.get(); TRACE(ext_data->tmp_array); //정상적으로 출력됨 TRACE("\r\n"); std::shared_ptr<StringContainer> * test_cstring = reinterpret_cast<shared_ptr<StringContainer> * >(extern_raw_cstring_address); //캐스팅된 변수가 이상함1 StringContainer* recover_raw_cstring = ( * test_cstring).get(); //내부 데이터 역시 깨져있음2 TRACE((*recover_raw_cstring).tmp_array); //여기서 종료됨3 TRACE("\r\n"); }
일단 제가 하려는게 다음과 같은겁니다.
함수 A()에서 shared_ptr를 만들고 그 주소를 저장합니다.
함수 B()에서 그 주소를 가지고 shared_ptr를 다시 가져옵니다.
하지만 함수B에서 실제 주소인 extern_raw_cstring_address를 가지고 shared_ptr를 다시 불러오면 데이터가깨져있어요
함수 A()벗어났을때 shared_ptr이 삭제된건 절대아니구요 (왜냐하면 deleter함수를 등록해서 확인해보면 확실히 ext_cr때문에 삭제 안시켜요)
왜 shared_ptr를 정상적으로 메모리에서 가져오지 못할까요?
함수B()를 함수 A() 끝나기 전에 불러도 정상적으로 출력이 되는데...함수 A()가 종료된뒤 함수 B()를 부르면 에러로 종료됩니다.
Forums:
shared_ptr은 내부의 pointer를 공유하는
shared_ptr은 내부의 pointer를 공유하는 그냥 객체입니다.
함수 A 종료시점에 cr과 ext_cr이 가지고 있는 내부 pointer는 유효하지만 cr은 종료되어버리므로,
그 cr의 pointer를 가지고 있는 extern_raw_cstring_address는 유효하지 않은 cr의 pointer를 가지고 있게 됩니다.
정말 그렇더라구요.. 그래서 shared_ptr를
정말 그렇더라구요..
그래서 shared_ptr를 클래스 넣어서 관리하는 것으로 변경하고 있습니다.
shared_ptr 과 new 사용방법
테스트해봤습니다.
http://en.cppreference.com/w/cpp/memory/shared_ptr
http://blog.naver.com/lobo_prix/220421546490
shared_ptr 을 전역변수로 사용하더라도. main함수가 return 될때.
소멸자가 자동으로 호출됩니다. delete p; 를 하지 않아도 되는 경우가 있습니다.
shared_ptr 을 지역변수로 사용하면. 함수가 return 될때. 소멸자가 함께 호출됩니다.
shared_ptr 은 같은 주소를 함께 참조하면 오류가 발생합니다.
---------------------------------------------
TRACE() 는 255 자를 넘을 경우. 주의해야 합니다.
사용방법은 printf() 와 같은 방식입니다.
TRACE 매크로
https://msdn.microsoft.com/ko-kr/library/4wyz8787%28v=vs.90%29.aspx
https://msdn.microsoft.com/en-us/library/6w95a4ha.aspx
---------------------------------------------
char buf[1024];
sprintf(buf, "%s", "test");
OutputDebugString(buf); 도 사용하실 수 있습니다.
---------------------------------------------
윈도우에서 콘솔화면을 띄워서. printf()를 사용할 수 있습니다.
AllocConsole();
freopen("CONOUT$", "wt", stdout);
콘솔 윈도우 닫기
FreeConsole();
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
그렇지 않아도 2번째 링크에서 지적한 문제가 저한테도
그렇지 않아도 2번째 링크에서 지적한 문제가 저한테도 발생해서
http://blog.naver.com/lobo_prix/220421546490
좀더 shared_ptr에 대해서 공부해봐야겠네요
테스트 감사해요
댓글 달기