다형성과 연관된듯한 메모리 누수 문제입니다.

pok의 이미지

CPUscheduleAL* pCPUscheduleAL = new FCFS;
...
delete pCPUscheduleAL;

CPUscheduleAL을 상속받는 클래스중에 FCFS라는 클래스가 있고, 다형성을 이용하기위해 위와 같이 선언을 했는데요, valgrind로 메모리누수 체크하는도중에 이부분에서 reachable block라고 나옵니다. 분명 delete를 해줬는데도요...

원인이 무엇일까요?

(음... 학교숙제 미워요.. 놀고 싶어요.)

lifthrasiir의 이미지

pok wrote:
CPUscheduleAL* pCPUscheduleAL = new FCFS;
...
delete pCPUscheduleAL;

CPUscheduleAL을 상속받는 클래스중에 FCFS라는 클래스가 있고, 다형성을 이용하기위해 위와 같이 선언을 했는데요, valgrind로 메모리누수 체크하는도중에 이부분에서 reachable block라고 나옵니다. 분명 delete를 해줬는데도요...

원인이 무엇일까요?

(음... 학교숙제 미워요.. 놀고 싶어요.)

저는 valgrind를 안 써 봐서(-_-;) 모릅니다만, 혹시 소멸자가 virtual이 아닌가요?

- 토끼군

pok의 이미지

소멸자는 virtual로 했는데, 딱히 소멸자에서 해주는 일은 없습니다.
단지 다을수만 있을뿐이야~ 하하~ (.....) 하면서 최면을 걸고 있습니다.

실행시에 별다른 문제가 있는것은 아닙니다. 그냥 조금 찝찝해서 여러분들은 어떤식으로 저러한 코드를 처리하며, 저렇게 처리하는것이 절차에 맞는것인지 궁금해서요..

쌀밥의 이미지

부모(이경우 CPUscheduleAL)의 소멸자가 virtual 이 아니면
(예를 들어 자식만 virtual)
메모리 누수가 발생할 가능성이 있습니다.

워낙 짧은 코드라서 절차에 맞고 안 맞고 따질것도 없어보이네요.ㅋ

참고로 저라면 이렇게 할것 같습니다.

CPUscheduleAL* const pCPUscheduleAL = new FCFS;

일하는 사람들의 희망 민주노동당 : http://www.kdlp.org
반공 교육의 성과로, 민주주의의 반대가 공산주의(또는 사회주의)라고 생각하는 사람이 많다.

pok의 이미지

답변들 정말 감사합니다. 그럼 염치불구하고 코드올려 부탁드리겠습니다.

class CPUscheduleAL {
	public:
		CPUscheduleAL(){
			pQueueReady_ = NULL;
			pQueueRun_ = NULL;
			pQueueNotYet_ = NULL;
			pQueueWait_ = NULL;
			pQueueHalt_ = NULL;
			
			TSC_ = 0;
			nowIo_ =0;
		}
		virtual ~CPUscheduleAL(){}
		virtual int checkReady() = 0;
		int checkWait();
		int checkNotYet();
		int checkRun();
		void setNotYetQueue(Queue* queueNotYet){pQueueNotYet_ = queueNotYet;}
		void setWaitQueue(Queue* queueWait){pQueueWait_ = queueWait;}
		void setRunningQueue(Queue* queueRunning){pQueueRun_ = queueRunning;}
		void setReadyQueue(Queue* queueReady){pQueueReady_ = queueReady;}
		void setHaltQueue(Queue* queueHalt){pQueueHalt_ = queueHalt;}
		void setTSC(int _TSC, int _running){TSC_=_TSC; cpuRunning_ = _running;}
		Pcb* getRunningPcb(){return pQueueRun_->getHead();}
		
	protected:
		Queue* pQueueReady_;
		Queue* pQueueRun_;
		Queue* pQueueNotYet_;
		Queue* pQueueWait_;
		Queue* pQueueHalt_;
		
		int TSC_;
		int cpuRunning_;
		int nowIo_;
};

class FCFS : public CPUscheduleAL {
	public:
		int checkReady();
	//private:
};

CPUscheduleAL의 파생클래스로 FCFS가 있고 SJF, RR등등이 있습니다.

CPUscheduler 이라는 클래스에서는 CPUscheduleAL을 Strategy Pattern으로 이용합니다.

class CPUscheduler {
	public:
                .....
		static CPUscheduleAL* createCPUscheduleAL(const char* _pAlgoType);
                .....
};

CPUscheduleAL* CPUscheduler::createCPUscheduleAL(const char* _pAlgoType){
	if(strcmp(_pAlgoType, "FCFS") == 0){
		return new FCFS;
	}

CPUscheduleAL* pCPUscheduleAL = CPUscheduler::createCPUscheduleAL(argv[2]);

pCPUschedulAL은 Factory Method Pattern으로 만들어지는데, 소멸은 위 코드처럼 제가 직접시켜줍니다. 더 좋은 방법있으면 지적부탁드립니다.

쌀밥 wrote:
참고로 저라면 이렇게 할것 같습니다.
CPUscheduleAL* const pCPUscheduleAL = new FCFS;

변하지 않는것은 상수로 쓰는것이 좋은건 알고 있는데, 당췌 상수성이 어디에 붙는건지 잘 몰라 활용을 못하는데(예를들면 CPUscheduleAL* const pCPUscheduleAL인게 옳은건지 const CPUscheduleAL* pCPUscheduleAL 가 옳은건지 등등) 참고할만한 문서(..이왕이면 한글로 되어있고 친절한..) 추천 부탁드리겠습니다.
쌀밥의 이미지

pok wrote:
변하지 않는것은 상수로 쓰는것이 좋은건 알고 있는데, 당췌 상수성이 어디에 붙는건지 잘 몰라 활용을 못하는데(예를들면 CPUscheduleAL* const pCPUscheduleAL인게 옳은건지 const CPUscheduleAL* pCPUscheduleAL 가 옳은건지 등등) 참고할만한 문서(..이왕이면 한글로 되어있고 친절한..) 추천 부탁드리겠습니다.

이 내용만 간단히 설명드리면
const 는 별표(*)를 기준으로 좌측과 우측이 다릅니다.

const int * a; 이것과 int const * a; 는 같은 의미가 되고요
a->a = 3; 이런걸 막게 됩니다. 포인트 하고 있는 메모리 공간에 대한 상수성을 정의합니다.

반면에
int * const a = new int; 이것은 a = new int; 와 같이 a가 가르키는 메모리 주소값 자체를 바꾸지 못하게 막습니다.

이 내용은 Effective C++ (스캇 마이어) 에 자세히 나와있었던걸로 기억합니다.
이책 안보셨다면 꼭 보시기를 권하고 싶습니다.
C++ 필독서입니다. (번역본도 볼만합니다.)

일하는 사람들의 희망 민주노동당 : http://www.kdlp.org
반공 교육의 성과로, 민주주의의 반대가 공산주의(또는 사회주의)라고 생각하는 사람이 많다.

쌀밥의 이미지

보여주신 소스 코드를 읽어봤습니다.

음. 사용되는 방식을 보지 못해서 잘 모르겠지만

CPUscheduleAL 객체가 소멸되는 시점에서
아래 맴버 변수들을 delete 해야하지는 않을까요?
Queue* pQueueReady_;
Queue* pQueueRun_;
Queue* pQueueNotYet_;
Queue* pQueueWait_;
Queue* pQueueHalt_;

위의 변수들을 소멸시켜주는 책임자가 따로 있다면
다른 부분에서는 문제가 될 것 같은 부분은 보이지 않네요...

그리고, 별 이유가 없다면 맴버 변수는 protected보다는 private에 넣는 것이 좋을듯 합니다.
그리고 protected에 넣어야 할 변수가 생긴다면 변수를 protected로 옮기지 말고 해당 변수에 접근하는 메소드를 protected에 추가하는 방식으로 하시는 것이 나중에 확장성을 고려했을때 좋다고 생각합니다.

그리고 쓸데 없는 사족을 더 달아보면, 생성자에서 초기화 리스트를 사용하면 어떨까요?
CPUscheduleAL()
: pQueueReady_(NULL)
, pQueueRun_(NULL)
, pQueueNotYet_(NULL)
, pQueueWait_(NULL)
, pQueueHalt_(NULL)
, TSC_(0)
, nowIo_(0)
{}

일하는 사람들의 희망 민주노동당 : http://www.kdlp.org
반공 교육의 성과로, 민주주의의 반대가 공산주의(또는 사회주의)라고 생각하는 사람이 많다.

pok의 이미지

쌀밥님. 답변감사합니다.
많이 배웠습니다. :D

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.