c++에서 메모리 해제 시 발생하는 문제

fopenfclose의 이미지

플레이어가 25장의 카드를 스택에 저장해서 갖고 있는데 게임을 하기 위해서 6장의 카드를 스택에서 뽑아야 합니다..

// 게임 실행 메소드
void CCardGameWorld::cardGameRun(CPlayer & gamer1, CPlayer & gamer2)
{
	int cardChoice[2];
 
	// 유저1 기본 세팅
	gamer1.cardShuffle();
	gamer1.cardPrint(CARDCOUNT);
	gamer1.pushCardStack();
	gamer1.getSixCard(); <- 문제는 이 메소드를 호출 했을 때 발생합니다. 
 
	// 유저2 기본 세팅
	gamer2.cardShuffle();
	gamer2.cardPrint(CARDCOUNT);
	gamer2.pushCardStack();
	gamer2.getSixCard();
 
	system("cls");
 
	cout << "플레이어1의 6장의 카드 리스트 목록" << endl;
	cout << "[player 1]" << endl;
	gamer1.showCard(gamer1.m_sixCard, SIXCARD);
	cout << endl;
 
	cout << "[player 1]은 한 장의 카드를 선택하세요" << endl;
	cout << "[1] [2] [3] [4] [5] [6]" << endl;
	cin >> cardChoice[0];
 
	cout << endl;
	cout << "플레이어2의 6장의 카드 리스트 목록" << endl;
	cout << "[player 2]" << endl;
	gamer2.showCard(gamer2.m_sixCard, SIXCARD);
	cout << endl;
 
	cout << "[player 2]은 한 장의 카드를 선택하세요" << endl;
	cout << "[1] [2] [3] [4] [5] [6]" << endl;
	cin >> cardChoice[1];
 
	Sleep(2500);
	system("cls");
....

우선 카드 클래스의 cpp 파일입니다.

// 생성자
CCard::CCard()
{
	// 초기화
	memset(&m_card, 0, sizeof(m_card));
	nodeNext = NULL;
}
 
CCard::CCard(Card card)
{
	m_card = card;
	nodeNext = NULL;
}
 
CCard::CCard(const CCard & copyCard)
{
	m_card = copyCard.m_card;
	nodeNext = copyCard.nodeNext;
 
}
 
// 소멸자
CCard::~CCard()
{
	if(nodeNext != NULL)
		delete nodeNext; <- 디버깅 했을 때 여기서 런타임 에러를 냅니다. 
}
 
// public method
// 카드 정보 리턴
Card CCard::getCard()
{
	return m_card;
}
 
// public method
// 카드 멤버 세팅
void CCard::setCard(Card  card)
{
 
}

스택 쪽 코드 입니다. 아래는 ,

// 전문화 템플릿 스택 팝
CCard CDeck<CCard *>::pop()
{
	if (m_top == NULL)
	{
		cout << "stack is empty" << endl;
		// 스택 비었을 때
		CCard wrongCard;
		wrongCard.m_card.cardType = WRONGCARD;
		return wrongCard;
	}
 
	CCard retCard = *m_top;
	retCard.nodeNext = NULL;
 
	CCard * retCardTemp = m_top;
 
	m_top = m_top->nodeNext;
	retCardTemp->nodeNext = NULL; // 
	delete retCardTemp;  // ?? 왜 주석 해제하면 런타임 에러가 날까요?? <- 이 코드를 삽입해서 컴파일하면 에러는 없는데 주석을 해제하면 런타임 때 죽습니다. 
 
	return retCard;
}

해제 시킨 곳을 또 해제해서 메모리 관련 에러로 프로그램이 죽는 줄 알고 그에 따른 처리를 했는데

원인이 해결되지가 않습니다. 무슨 문제가 있는 것인지 가르쳐주세요!! 감사합니당

File attachments: 
첨부파일 크기
Package icon TicTacToeProj.zip6.08 KB
hano881112의 이미지

CCardGameManager의 setCard에서 초기화를 해주고 있는데

a_pCard[i] = new COCard[1];

배열 형식으로 초기화를 합니다.

그런데 delete[]로 메모리를 해제해주는 게 아니라 delete로 메모리를 해제하고 있어서 문제가 되지 않을까요?

딱히 컴파일을 해본 건 아니고 슬쩍 본 거라 확답은 아닙니다.. ㅎㅎ..

balgarac1의 이미지

답변감사드립니당!!

hano881112의 이미지

그런데 왜 배열로 객체를 생성하셨나요? ㅎㅎ 궁금하네요.
그리고 모던 c++을 사용하신다면 raw pointer보다는 스마트 포인터를 활용하는 게 좋을 거 같습니다.
그럼 new / delete, new[] / delete[] 페어를 생각하지 않아도 되기 때문에 안전하고 편리합니다.

shint의 이미지

_msize() 는 윈도우에서만 가능하며.
malloc() 으로 메모리를 할당한 경우. 값을 확인하기 좋다.

_msize() 로 클래스를 메모리에 할당하면. 생성자. 소멸자만 있는 경우. 1바이트가 나온다.
멤버 변수가 있으면. 그 크기 만큼 출력 된다.

#include <iostream>
#include <stdlib.h>
 
 
class CTest
{
public:
    CTest()
    {
        printf("생성자\n");
    }
    ~CTest()
    {
        printf("소멸자\n");
        printf("\n");
    }
};
 
 
int main(int argc, char** argv) 
{
    {
        printf("CTest ct;                 \n");
        CTest ct;
    }
 
    {
        printf("CTest *p = new CTest();   \n");
        printf("delete [] p;              \n");
        printf("생성자 호출후. 소멸자 무한 반복. 소멸자를 virtual 하면 오류. \n");
    #if 0
        CTest *p = new CTest();
        delete [] p;
    #endif
        printf("\n");
    }
 
    {
        printf("CTest *p = new CTest();   \n");
        printf("delete p;                 \n");
        CTest *p = new CTest();
        printf("_msize [ %d]\n", _msize(p));
        delete p;
    }
 
    {
        printf("CTest *p = new CTest;     \n");
        printf("delete p;                 \n");
        CTest *p = new CTest;
        printf("_msize [ %d]\n", _msize(p));
        delete p;
    }
 
    {
        printf("CTest *p = new CTest;     \n");
        printf("delete [] p;              \n");
        printf("생성자 호출후. 소멸자 무한 반복. 소멸자를 virtual 하면 오류. \n");
    #if 0
        CTest *p = new CTest;
        delete [] p;
    #endif
        printf("\n");
    }
 
    {
        printf("CTest *p = new CTest[0];  \n");
        printf("delete [] p;              \n");
        printf("생성자와 소멸자가 호출이 안됨. \n");
    #if 1
        CTest *p = new CTest[0];
        printf("_msize [ %d]\n", _msize(p));
        delete [] p;
    #endif
        printf("\n");
    }
 
    {
        printf("CTest *p = new CTest[1];  \n");
        printf("delete [] p;              \n");
    #if 1
        CTest *p = new CTest[1];
        printf("_msize [ %d]\n", _msize(p));
        delete [] p;
    #endif
        printf("\n");
    }
 
	return 0;
}

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

shint의 이미지

저도 오류가 보였던거 같기도 하지만. 나타나지 않네요...??

- 초기화 확인
- 값 확인
- 주소 확인

- 소스를 나눠서 컴파일해서 확인
- 되도록 인자값에 연산자를 넣지 않아야 합니다. buf[10+20+30];

delete 전에 조건문을 줘보세요.

if( retCardTemp != NULL )
{
    delete retCardTemp;
}

-1 하는것이 추가되야 할거 같습니다.

	if (gamer1.m_sixCard[cardChoice[0]-1].m_card.cardNumber > gamer2.m_sixCard[cardChoice[1]-1].m_card.cardNumber)
{
}
	else
{
}


메모리 릭 처리 내용을 포함해봤습니다.

도스 프롬프트 - 콘솔 윈도우 화면 크기 바꾸는 방법'도 참고해보세요.

댓글 첨부 파일: 
첨부파일 크기
Package icon TicTacToeProj_0 수정본.zip412.32 KB
Image icon K-20151211-468326.png157.73 KB
Image icon K-20151211-468415.png11.5 KB

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

balgarac1의 이미지

감사합니다. 매번 친절하게 답변 주셔서...ㅜ

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.