[완료]소멸자 호출과 메모리 free되는 시점 및 간단한 연산자 오버로딩에 대한 질문입니다
소멸자가 호출되는 시점과 간단한 연산자 오버로딩에 대한 질문입니다.
컴파일은 VC++ 6.0을 사용하였구요.
첨부파일 프로그램을 컴파일해보면 에러가 발생하는데요.
바로 소멸자에서 메모리 해제하는 부분입니다.
디버깅을 해보면 return으로 종료되기 직전에 순서대로(m1~m5) 소멸자가 호출되는데요.
Delete_Value()함수를 이용해 메모리 해제시에는 에러가 발생하지 않는데,
소멸자 호출시 에러가 발생하는 이유는 무엇인지요?
그리고 연산자 오버로딩시 포인터를 사용하고 싶은데요.
예를들어 클래스 Cm의 크기를 동적으로 만들어 쓰고 operator+를 객체의 숫자에 상관없이
사용하고 싶은데 에러가 발생하네요. 추가코딩 부분과 에러의 내용은 아래와 같습니다.
int m = 4;
Cm *pm1, *pm2, *pm3;
pm1 = new Cm(m);
pm2 = new Cm(m);
pm3 = new Cm(m);
pm3 = pm1 + pm2;
에러내용 : error C2110: cannot add two pointers
현재 operator+는 call by value에 의해 값을 전달하므로 다음의 operator+함수를 추가 하였습니다.
Cm * operator+(const Cm *mm)const
{
Cm * tc;
tc = new Cm(nn);
for(int i=0; i
{
tc->dp[i] = dp[i] + mm->dp[i];
}
return tc;
}
그래도 같은 에러가 발생하네요.
에러내용 : error C2110: cannot add two pointers
책도 읽어보고 예제도 많이 찾아봤지만 해답을 찾지못해 여기 글을 올려봅니다.
첨부 | 파일 크기 |
---|---|
및 전체글.txt | 2.09 KB |
1. 소멸자가 아니라
1. 소멸자가 아니라 복사생성자를 정의하지 않았기 때문입니다. 해제된 포인터를 다시 해제해서 문제가 터지는 것입니다.
2. op+를 멤버로 정의하지 말고 비멤버함수로 정의해야합니다.
:)
1. 소멸자가 아니라...
netionics님의 댓글 감사드립니다.
// 1. 소멸자가 아니라 복사생성자를 정의하지 않았기 때문입니다. 해제된 포인터를 다시 해제해서 문제가 터지는 것입니다.
말씀하신대로 복사생성자를 아래와같이 추가하여 코딩하였으며 에러를 해결하였습니다.
Cm(const Cm & copy)
{
nn = copy.nn;
dp = (double *)calloc(nn, sizeof(double));
for(int i=0;i dp[i] = copy.dp[i];
}
복사생성자의 용도를 명확히 이해하는 좋은 시간이었습니다. ^^*
2. 비멤버함수로 작성하여 해결하였습니다. 감사합니다~
...
시간이 없어서 첨부된 내용은 확인하기 어렵고..
operator+와 관련된 부분만 말씀드리면,
pm3 = pm1 + pm2;
이 부분은 모호한 문법이네요.
포인터의 주소를 더해서 주소에다 저장하라는 것인지.. 아니면 operator+를 호출하라는 것인지 모호합니다. 컴파일 된다고 해도 컴파일러에 따라 버그가 될 가능성이 높네요.
일반적으로 operator overloading시, 인자는 const &형을 많이 사용합니다.
그리고 리턴 값도 내부에서 메모리를 할당하고 외부에 던져주는데,
이러한 방식은 모르고 사용하면 찾기 힘든 버그가 됩니다.
제대로 쓴다고 해도 덧셈을 사용할 때 마다 메모리를 할당하기 때문에 엄청난
외부 및 내부 fragmentation이 예상되는 군요...
coding standard나, effective c++등의 책을 보면 효율적인 operator overloading 방식에 대한 내용이 있습니다. 책을 참조하고 만드시면 좋겠네요...
_________________________________________________________
nineye's blog
_________________________________________________________
nineye's blog
포인터 덧셈 부분은..
연산자 재정의를 하시더라도
*pm3 = *pm1 + *pm2;
이런식으로 구현하시는게 혼동도 없고 더 나은 방식이 아닐까 합니다.
--
This is for you new people. I have just one rule :
Everyone fights, no one quits. If you don't do your job, I'll shoot you myself. Do you get me?
--
nineye님과 mirheekl님의 글
nineye님의 글 감사드립니다.
말씀하신 책 참고하겠습니다. ^^*
mirheekl님의 글도 감사드립니다.
현재 수정하려는 클래스에서 operator의 사용목적은
포인터의 덧셈이 아닌 클래스 내부 double형 포인터의 번지가 아닌 값을 더하려고 하는 거구요.
클래스 초기화시 이 double형 포인터의 크기는 가변적으로 변하게 생성자를 만든겁니다. ^^*
이게 좀 애매모호한 부분이 있네요. ^^;
댓글 달기