c++에서 오브젝트 리턴 시 자동으로 삭제되는 문제

keoldn1의 이미지

행렬 관련 프로그램을 작성하고 있습니다.
연산자 오버로딩으로 연산을 수행한 후, 결과 객체를 리턴하고자 합니다. 그런데 리턴이 되기 전에 destructor가 호출되서 메모리를 다 정리해버리더군요. 그래서 리턴 객체의 함수를 호출하면 에러가 발생합니다. 어떻게 해결할 수 있을까요??....

class matrix{
public:
	int **mat;
 
	matrix(int size_){size=size_;mat=NULL;create();}
	~matrix();
 
	void create(int size_=0);
 
	int& operator()(int i,int j) const{return *(*(mat+j)+i);}
	friend matrix& operator+(const matrix& lop,const matrix& rop); 
};
 
matrix::~matrix(){
	int cnt=size;
	while(cnt--) free(*(mat+cnt));
	free(mat);
}
 
void matrix::create(int size_){
	int sz;
	int cnt=size;
 
	if(size_) {sz=size_; size=size_;}
	else {sz=size;}
 
	if(mat==NULL){
		mat=(int **)malloc(size*sizeof(int *));
		while(sz--) *(mat+sz)=(int *)malloc(size*sizeof(int));
	}
	else{
		while(cnt--) free(*(mat+cnt));
		free(mat);
		mat=(int **)malloc(size*sizeof(int *));
		while(sz--) *(mat+sz)=(int *)malloc(size*sizeof(int));
	}
}
 
void matrix::print(){
	for(int j=0;j<size;j++) {
		for(int i=0;i<size;i++) printf("%d ",(*this)(i,j));
		printf("\n");
	}
}
 
matrix& operator+(const matrix& lop,const matrix& rop){ 
	matrix ret(lop.size);
	for(int i=0;i<lop.size;i++) for(int j=0;j<lop.size;j++) 
		ret(i,j)=lop(i,j)+rop(i,j);
	return ret;
}
 
 
int main(int argc,char **argv){
	matrix mat;
	matrix mat2;
 
	..........
	..........
 
 
	(mat+mat2).print();
}
gilgil의 이미지

matrix& operator+(const matrix& lop,const matrix& rop){ 
	matrix ret(lop.size);
	for(int i=0;i<lop.size;i++) for(int j=0;j<lop.size;j++) 
		ret(i,j)=lop(i,j)+rop(i,j);
	return ret;
}

본 메소드에서 보면 return object는 method 내부에 있는 ret라는 객체인데요, 이 놈은 local stack에서 생성이 되었다가 method가 종료되는 시점에 객체 해제가 됩니다. 해제된 object를 reference로 받아서 사용(main에서 (mat+mat2).print() 를 하게 되니, 당연히 비정상 작동을 하게 될 것입니다.

[해결 방안]
1. return type을 reference 혹은 pointer로 반환을 하려면 return 객체가 method 종료되는 시점에 해제되지 않도록 한다. 예를 들어 return되는 object를 local에 두지 말고 클래스의 member로 두도록 한다.

2. operator+ 의 return type을 reference나 pointer type으로 하지 말고 그냥 그 type 그대로 반환해 준다.
matrix operator+(const matrix& lop,const matrix& rop){ // & 를 뺄 것.

관련된 테스트를 예전에 해 본 적이 있으니 참고하시기 바랍니다.
http://www.gilgil.net/10970

keoldn1의 이미지

2번째 방법으로 하니깐 되네요 ㅠㅠㅠㅠㅠ 거의 몇시간 걸렸는데.. 간단하네요ㅠㅠ..

댓글 달기

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