C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[71183] Re:Re:메소드에서 선언된 지역변수 메모리 해제 관련질문...
pwrlove [pwrlove] 4310 읽음    2014-04-10 17:23
아, 한가지 원하시는 답을 하지 않은 것 같네요.

1) 지역변수에 할당한 객체는 그 매쏘드를 리턴하게 되면, 그 지역 변수는 자동으로 소멸됩니다.

2) 다만, 지역변수를 포인터로 선언하고, new로 할당한 객체는
매쏘드 리턴이 되었을 경우, 지역변수 포인터만 자동으로 없어지고,
힙에 할당된 내용은 그대로 남아있게 됩니다. 그런 경우 바로 메모리 누수가 생기는 것 입니다.

1)과 2) 경우를 잘 구분하셔야 합니다.

1)의  경우는 별 문제 없이 소멸이 되지만, 주의하셔야 할 것은 이 경우, 그 객체에 & 붙여서 참조형태로 리턴하여
외부로 내 보내면 매우 위험합니다. 제가 주위에서 초보 개발자들에게서 매우 자주 발견하는 실수들 입니다.
-> 이유는 이 객체는 힙에 생성된 객체가 아니고 스택에 생성된 객체인데, return을 만나는 순간 어떻게 정리가 될지 아무도
    알수 없기 때문입니다. Access violation 일으키는 주범입니다.

2)의 경우는 매쏘드를 리턴하기 전에 반드시 처리를 해 줘야 합니다.
이 경우를 위해 객체의 위임관계를 정리하셔야 합니다.

이 객체를 지금 없애야 하는지? 아니면 다른 곳으로 위임을 해서 보존을 해야 하는지?
리턴이 오기전에 이 상황을 결정해야 하는 것입니다.

사실 경험이 많은 개발자들도 이 관계를 잘 정리하지 않아서 혹은 순간 헷갈려서, 종종 메모리 누수를 만듭니다.
멀티쓰레드에서는 각 객체간의 수명관계를 정리하기가 또한 쉽지 않습니다.

그냥 코딩 레벨에서 파악한 내용으로 실제 런타임의 상황을 정확히 예측하는 것은 가능하지 않습니다.
그래서 종종 먼저 제거되어버린 객체를 사용하려고 접근하는 경우도 많이 발생합니다. 이런 경우 dangling 포인터
오류, 역시 Access violation을 일으킵니다. 고수들도 많이 실수를 합니다.

이런 어려운 시스템적인 것들을 개발자가 핸들링해야 한다는 것이 C/C++의 어려운 점입니다.
이런걸 어느정도 극복하려면, 상당한 숙련 기간이 필요합니다.
대규모의 솔루션을 구축하는데는 한계가 분명 있습니다.

그래서 현대적인 언어들(자바, 스크립트성 언어들)은 이런 기능을 시스템에서 해 주도록 장착이 되었죠.
그것이 바로 Garbage Collector 입니다.  물론 장단점이 있긴 하지만요.

그래서 이런 부분들이 쉽지 않기 때문에 기계적 코딩을 할 수 있도록 정리된 것들이 디자인 패턴 입니다.

참고 바랍니다.

pwrlove 님이 쓰신 글 :
:
: 아래의 주신 질문이
:
: 어떤 특정한 객체내의 매쏘드를 말하시는 거라면,
: 먼저 그 매쏘드가 속한 객체의 수명과의 관계를 먼저 결정하셔야 할 듯 합니다
:
: 만약, 매쏘드내에서 사용하고자하는 컴포넌트 객체가 앞에서 말씀드린 객체와 같다면
: 그 객체의 멤버로 선언을 변경 하시면 될 듯 하고요,
:
: 그렇지 않고, 매쏘드내에서만 유효하다는 판단을 하시면 그 매쏘드내에서만 살아남도록 처리하면 될듯 합니다.
: 그런데, 그도 저도 잘 모르겠다면, 그냥 멤버 변수로 하셔도 될듯합니다(매우 힙을 심각히 많이 사용한다면 제외.)
:
: 변수 라이프싸이클 관리와 관련하여 한가지 요령은
: 이게 잘 판단되지 않으시면, 저의 경우는 그냥 멤버 변수로 포인터 선언하시고, 생성자에서 널로 초기화 하신다음.
: 호출되는 매쏘드에서 널이면 생성하여 사용하고, 아니면 객체를 해제하거나 경우에 따라서 초기화 매쏘드가 지원되면
: 재 사용하는 방법으로 하면 별 문제 없습니다. 물론 어디서든지 해제하고 반드시 포인터에 널만 채워 놓으면 됩니다.
:
: 물론 소멸자에서 객체가 살아있다면 해제하면 되죠.
:
: 그 외 글로벌 객체로 선언하는 것은 별로 권장하고 싶지 않습니다.
: 물론 편한 경우도 많지만, 일반적으로 사용하지 않도록 해야 합니다.
:
: 가장 하지 말아야 할것은 매쏘드내 지역 변수 포인터에 할당된 객체를 리턴하여 외부로 내 보내는 것입니다.
: 그렇게하면 객체의 소유관계가 불 분명하게 되고, 그 객체를 해제 하지 않을 가능성이 높아집니다.
:
: 그런 경우는 객체 위임 관계에 대한 내용 정리하시면 됩니다.
: 뭐, aggregation, composition 이런 내용 구글링하시면 됩니다.
:
: 그리고, 디자인 패턴 잘 공부해 두시면 도움이 됩니다.
:
: 아래의 내용 정리해 보세요.
:
: 1) 변수를 정의하면 메모리 구조에 어떻게 할당되는지 정리
:     코드영역 > 데이터 영역 > 힙영역 > 스택영역
:
: 2)  1) 항목에 따른 변수의 수명 관계 정리.
:     -> 예) 지역변수는 스택에 생성이 되고, 함수를 리턴하면 자동으로 없어진다.
:
: 너무 정신없게 설명했나?
:
: 참고 바랍니다.
:
:
:
: 만나바 님이 쓰신 글 :
: : 메소드에서 new를 통해 컴포넌트 객체를 생성한다음에 메모리를 해제할려면
: : 해당 메소드 안에서 메모리를 해제 해야되는걸로 알고 있는데 해당 메소드 안에서 객체의
: : 메모리를 해제하면 메소드 호출시 해당 컴포넌트 객체가 바로 삭제되는거자나요.
: : 지역변수처럼 선언된 객체를 해제 하려면 어떻게 해야할까요? ( 변수들을 다 전역변수로 선언해야할까요?)

+ -

관련 글 리스트
71154 메소드에서 선언된 지역변수 메모리 해제 관련질문... 만나바 4528 2014/04/04
71182     Re:메소드에서 선언된 지역변수 메모리 해제 관련질문... pwrlove 3154 2014/04/10
71183         Re:Re:메소드에서 선언된 지역변수 메모리 해제 관련질문... pwrlove 4310 2014/04/10
71157     Re:메소드에서 선언된 지역변수 메모리 해제 관련질문... 빌더초보 4800 2014/04/04
71184         Re:Re:메소드에서 선언된 지역변수 메모리 해제 관련질문... pwrlove 3328 2014/04/10
71217             Re:Re:Re:메소드에서 선언된 지역변수 메모리 해제 관련질문... pwrlove 3136 2014/04/14
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.