[c++] 멤버함수 내에서 자기 자신을 삭제 해도 될런지요?
글쓴이: inootis / 작성시간: 화, 2003/05/20 - 1:54오전
코드를 간략하게하면 아래와 같습니다.
std::map<std::string , test *> m; class test : public thread { public : void run() { m[id]=this; // 어쩌구 저쩌구... // 원하는 작업을 수행; // 어쩌구 저쩌구.. delete m[id]; m.erase(id); } }; (new test())->start("id001"); // id값 전달과 동시에 쓰래드를 생성
위처럼...맵을 이용해서 test객체를 관리하는 작업을 하려 합니다.
외부에서 생성해서 내부에서 파괴되도록했는데....이렇게 해도 되는지요? 제 생각에는 내부에서 파괴를 시키면 자기 자신을 잃어버려서 에러를 발생할것 같았는데..에러를 발생하지 않고 원하는 결과물이 나오네요..함수 마지막에 호출해서 문제가 없는건가요-_-a?
저 코드가 아무래도...이상한것 같아..이렇게 여쭈어봅니다.
Forums:
얼레???ㅡ_-) 윈도우즈에서 예~~~~~전에 그와 비슷하게 놀았
얼레???
ㅡ_-) 윈도우즈에서 예~~~~~전에 그와 비슷하게 놀았다가
메모리 접근 오류 났었는데... ㅡ_-); 되는 거였나요...?
_____________________________
언제나 맑고픈 샘이가...
http://purewell.biz
음... 저도 그렇게 써봤는데 전, 문제가 없었던 걸로 기억합니다.
음... 저도 그렇게 써봤는데 전, 문제가 없었던 걸로 기억합니다.
실제로 pObj->MyName 이라고 메서드를 호출하면 실제로는
MyName( pObj, 파라매터들 ) 로 바꿔서 호출 되는 거 아닌가요?
그러면, 실제로 delete를 하더라도 문제가 없을 것 같기도 한데... 음...
확실히 아시는 분 정확히 답변좀... 아니면, 어셈으로 만들어서 한번
따라가 봐야겠네요. 그럼 고운 하루.
=========================
CharSyam ^^ --- 고운 하루
=========================
new, delete 에서는 위험하지만, 구현을 잘 생각하면 그런 트릭을
new, delete 에서는 위험하지만, 구현을 잘 생각하면 그런 트릭을 이용할 수 있습니다.
member function의 개념은
1. 첫번째 인자를 this pointer로 넘기는 함수.
2. function mangling(decoration)에 class 이름이 들어가는 함수
3. 컴파일 때, class 내부에 선언된 변수,함수를 접근가능한 함수.
일 뿐입니다.
멤버가 자기자신을 죽인다고 생각하지 않고, 첫번째 인자를 "다루고 있다" 정도로 생각하시면 됩니다.
멤버 변수를 전혀 접근하지 않는 member 함수가 있으면, null pointer에서도
실행이 됩니다.
보통 이런 경우에는 test 를 static 으로 만들어주지요. static 은 첫번째 인자로 this가 넘어가지 않는 함수입니다.
delete 도 마찬가지 입니다 첫번째 인자가 단지 this pointer인 함수라고 생각하시면됩니다.
---
http://coolengineer.com
[code:1]std::map<std::
delete가 수행하는 일은 m[id]를 지우는 일 즉, 간단하게 말씀 드리면 동적 메모리를 제거하는것입니다. 함수의 경우엔 text 즉 명령라인에 해당 되기 때문에, 상식적으로 이런 명령라인까지 제거 되진 않겠죠? 프로세스를 이루는 요소는 text, data, 하나가 뭐였는지 가물가물 @_@ 입니다. 이중 data에 해당 되는 부분으론 stack, heap등이 있겠죠.
그리고 m은 map template이고 각 노드가 가지고 있는 값은 test클래스 인스탄스의 포인터에 해당되겠죠?
물론 이미 지워져 버린 메모리[흔히 유효하지 않은 영역이라고들 합니다.]로 억세스는 가능합니다. 메모리의 논리적인 개체를 지우는것이지 실제로 메모리를 뽀개?는건 아니죠^^; 물론 delete node; node = 0; 했다면 당연히 널포인터 예외가 나겠죠.
그래서 보통 이런 경우엔 isAvailable과 같은 멤버를 파괴자에서 거짓으로 만들어 유효하지 않은 개체임을 나타냅니다. 이런 경우에 파괴자가 쓰이는거죠^^; 파괴자를 잘 활용하시면 여러 모로 많은 도움이 되실겁니다. 특히 메모리단편화와 관련해서 리사이클링을 할 경우엔 더욱더 필요하게 됩니다.
delete this; 한 후에 해당 멤버의 필드나 메소드를 사용하지 않
delete this; 한 후에 해당 멤버의 필드나 메소드를 사용하지 않기만 하면 됩니다. 즉 delete this; 한 후에는 바로 메소드에서 반환되게 하면 되겠지요
저같은 경우 State pattern에서 state transition시에 유용하게 사용하고 있습니다. 깔끔한 해결책 같지는 않지만요;;
skjk님에 한표......저도 MFC에서 skjk님 처럼 써서 문제
skjk님에 한표......
저도 MFC에서 skjk님 처럼 써서 문제 없이 잘 돌아 가고 있습니다.
하지만 delete this; 이후에 멤버 함수나 멤버 변수에 접근한다면
어떻게 될지 아시겠죠.....
덧붙여서요 ^^
delete this;
이후에 멤버를 접근해도 아무런 오류는 나지 않습니다. 제가 앞에서 말씀 드렸듯이, 위의 연산을 행하고 나면 해당 블럭을 재사용가능한 리스트에 추가하게 됩니다. 파괴자에서 특별한 일을 하지 않는한...
위의 인스턴스에 대한 포인터 접근시에 아무런 언어적 오류는 생기지 않겠죠. 단 멀티쓰레딩을 하는 경우에 동기화와 관련된 문제가 생기겠죠. 포인터는 포인터고 메모리 블럭은 메모리 블럭이니깐요.
특정 멤버함수내에서 this역시 자기자신의 메모리 블럭에 대한 포인터에 불과합니다.
간단하게 다음의 코드를 테스트 해보시기 바랍니다.
결과는
0x8049e38
4
call method
0x8049e38
4
0x8049e38
4
가 나오게 됩니다.
여튼 위의 여러님들이 충고 하신것 처럼 특정멤버함수내에서 delete하는 것은 피하시기 바랍니다.
Re: 덧붙여서요 ^^
음...
경험과 표준은 구별해야겠지요... ^^
---
http://coolengineer.com
그럼 다른 방법에는 무엇이 있을까요? 다른 방법으로 일정시간 마다 tes
그럼 다른 방법에는 무엇이 있을까요? 다른 방법으로 일정시간 마다 test쓰레드의 상태를 조사해서 test쓰레드가 종료되었으면 메모리를 해제 해주는 쓰레드를 만들어 관리하는것을(가비지컬렉터와 같은..)...생각해 보있는데..비용이 많이 드는것 같아서..아직..구현을 안하고 있는데..(이방법이 더 좋을려나??;;)
문제는...외부에서 객체가 언제 종료될지 모른다는것인데...
여러분의 노하우를 듣고 싶네요;
댓글 달기