c++에서 메모리 해제 시 발생하는 문제
글쓴이: fopenfclose / 작성시간: 목, 2015/12/10 - 7:57오후
플레이어가 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:
| 첨부 | 파일 크기 |
|---|---|
| 6.08 KB |
Forums:


제 생각에는..
CCardGameManager의 setCard에서 초기화를 해주고 있는데
a_pCard[i] = new COCard[1];
배열 형식으로 초기화를 합니다.
그런데 delete[]로 메모리를 해제해주는 게 아니라 delete로 메모리를 해제하고 있어서 문제가 되지 않을까요?
딱히 컴파일을 해본 건 아니고 슬쩍 본 거라 확답은 아닙니다.. ㅎㅎ..
답변감사드립니당!!
답변감사드립니당!!
그런데 왜 배열로 객체를 생성하셨나요? ㅎㅎ
그런데 왜 배열로 객체를 생성하셨나요? ㅎㅎ 궁금하네요.
그리고 모던 c++을 사용하신다면 raw pointer보다는 스마트 포인터를 활용하는 게 좋을 거 같습니다.
그럼 new / delete, new[] / delete[] 페어를 생각하지 않아도 되기 때문에 안전하고 편리합니다.
이것을 참고해보시기 바랍니다.
_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
참고해보세요.
저도 오류가 보였던거 같기도 하지만. 나타나지 않네요...??
- 초기화 확인
- 값 확인
- 주소 확인
- 소스를 나눠서 컴파일해서 확인
- 되도록 인자값에 연산자를 넣지 않아야 합니다. 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 { }메모리 릭 처리 내용을 포함해봤습니다.
도스 프롬프트 - 콘솔 윈도우 화면 크기 바꾸는 방법'도 참고해보세요.
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
감사드립니다!!
감사합니다. 매번 친절하게 답변 주셔서...ㅜ
댓글 달기