C를 리턴하는 과정 도움 부탁드립니다.(초보올림)
글쓴이: chaosman / 작성시간: 토, 2013/10/05 - 10:18오전
이게 c를 리턴하는 과정에서 에러가 나는데 왜 에러가 나는지랑 어떻게 수정해야될지 감을 못잡겠어요 ㅜㅜㅜ
#include<iostream> using namespace std; class c { public: c(int n) : n(n) { p = new int[n]; }; c(const c &o) : n(o.n) { p = new int[n]; for(int i=0; i<n; i++) p[i] = o.p[i]; } ~c(void) { if (p!=NULL) delete[] p; }; private: int n,*p; }; c f(void) { c c(5); return c; } void main(void) { c c(5); c = f(); }
Forums:
컴파일 에러인가요? 실행 에러인가요? 일단 코드는
컴파일 에러인가요? 실행 에러인가요?
일단 코드는 문제가 없어 보이지만.
f에서 리턴하면서 배열이 사라져 버리기 때문에,
이 데이터를 이용하는 코드에서는 에러가 날 것입니다.
정확한 지적 같습니다. C++ 에서 '클래스 객체를
정확한 지적 같습니다.
C++ 에서 '클래스 객체를 리턴할 수 있느냐 없느냐'를 모르겠는데요. 그 문제를 차치하고서라도 클래스 객체는 로컬 변수로 선언되어 있습니다. 당연히 함수가 리턴하면... 문제가 발생하겠지요. 함수에서 클래스 객체의 포인터를 리턴한다고 해도 문젭니다.
이런 수준의 답변을 올리시는 분이
이런 수준의 답변을 올리시는 분이 http://kldp.org/node/116742 이 글에서 자신을 "개발자"라고 칭하면서 우리나라의 IT업계 환경을 이야기하고 계셨던 건가요?
정말 충격이네요
글을 봐서 직업 수평이동후 3년이 지난 시점입니다.
글을 봐서 직업 수평이동후 최대 3년이 지난 시점입니다. 그럴수도 있지요.
적대감이 충만한 글입니다. 왜 이런 글을 익명으로
적대감이 충만한 글입니다. 왜 이런 글을 익명으로 남기시는지 모르겠네요.
C++을 공들여 공부한 적은 있지만 개발하면서 거의 써본적이 없는 언어입니다. 주로 C를 썼지요. 틀릴 수도 있다고 생각합니다.
제가 실력이 없다고 합시다. 실력이 없으면 입을 막고 살아야 하나요? 정치학을 전공하지 않았으면 정치에 대해서 얘기하지 못하나요?
괜히 C++에 대해서 아는 척을 했다면 미안합니다. 하지만 님의 태도는 정말 이해하기 힘드네요. 님의 존재는 제가 한국을 그토록 떠나고 싶었던 이유중의 하나입니다.
제가 아주 실력이 넘치는 사람이 아니라는 것은 스스로 잘 압니다. 그리고 아주 훌륭한 사람이 아니라는 것도 잘 압니다. 하지만 한국인들의 그 놀라운 태도는 사람의 학을 떼게 만드는 무엇이 있는 것 같습니다.
이젠 kldp도 접어야할 때가 된 것 같군요. 마음이 많이 아프네요. 이런 식의 글이란.
마음 속으로는 님이 앞에 있다면 죽도록 패버리고 싶지만. 전 싸이코패스가 아닌 관계로 그렇게까진 할 수 없을 거 같고... 그냥 그렇게 사시길 바랍니다.
...
복사생성자만 있고 operator=이 없으니 맨 마지막에 c = f()를 실행할 때 그냥 임시객체의 내용을 (n과 p의 값) main의 로컬변수 c에 복사해 버릴 테고, 그 다음에 임시객체와 로컬변수 c에 대해 각각 소멸자가 불리면 같은 포인터 p에 대고 delete를 두 번 날리겠네요.
operator=의 부재까지는 맞았으나 delete를
operator=의 부재까지는 맞았으나 delete를 두 번 날리진 않습니다. 소멸자에서 p의 NULL여부를 검사하거든요.
죄송합니다. 소멸자에서 delete하고 p에
죄송합니다. 소멸자에서 delete하고 p에 NULL을 assign하진 않네요.
참고로 delete 는 원래 널포인터에 대해서는 아무
참고로 delete 는 원래 널포인터에 대해서는 아무 동작도 하지 않습니다. 따라서 이경우 널 포인터 검사는 시작적 효과외에는 의미가 없습니다.
이 경우엔 NULL을 넣어도 소용없죠.
소멸자가 두 번 불리는데 한번은 임시객체의 p, 또 한번은 main의 로컬변수 c의 p를 검사합니다.
그러니까 한쪽에서 delete하고 NULL을 넣어도 다른쪽 소멸자의 동작에 아무런 영향을 주지 않습니다.
deep copy & shallow copy 문제네요.
이 코드에서 deep copy가 이루어 지지 않고 shallow copy가 이루어 짐.
f() 함수 반환 객체(1번)과 c 객체(2번)의 p 포인터가 동일한 위치를 가리키게 되어서,
1번, 2번 객체의 해제 단계에서 동일한 포인터를 2번 delete해 버리는 구조.
jick님이 답변다셨듯이 operator= 를 overloading을 해서 p 포인터를 복사하시면 될 것 같습니다.
http://en.wikipedia.org/wiki/Object_copy
www.gilgil.net
댓글 달기