[완료]소멸자 호출과 메모리 free되는 시점 및 간단한 연산자 오버로딩에 대한 질문입니다

pursy의 이미지

소멸자가 호출되는 시점과 간단한 연산자 오버로딩에 대한 질문입니다.

컴파일은 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

책도 읽어보고 예제도 많이 찾아봤지만 해답을 찾지못해 여기 글을 올려봅니다.

File attachments: 
첨부파일 크기
Plain text icon 및 전체글.txt2.09 KB
netionics의 이미지

1. 소멸자가 아니라 복사생성자를 정의하지 않았기 때문입니다. 해제된 포인터를 다시 해제해서 문제가 터지는 것입니다.
2. op+를 멤버로 정의하지 말고 비멤버함수로 정의해야합니다.

:)

pursy의 이미지

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. 비멤버함수로 작성하여 해결하였습니다. 감사합니다~

nineye의 이미지


시간이 없어서 첨부된 내용은 확인하기 어렵고..
operator+와 관련된 부분만 말씀드리면,
pm3 = pm1 + pm2;
이 부분은 모호한 문법이네요.
포인터의 주소를 더해서 주소에다 저장하라는 것인지.. 아니면 operator+를 호출하라는 것인지 모호합니다. 컴파일 된다고 해도 컴파일러에 따라 버그가 될 가능성이 높네요.

일반적으로 operator overloading시, 인자는 const &형을 많이 사용합니다.
그리고 리턴 값도 내부에서 메모리를 할당하고 외부에 던져주는데,
이러한 방식은 모르고 사용하면 찾기 힘든 버그가 됩니다.
제대로 쓴다고 해도 덧셈을 사용할 때 마다 메모리를 할당하기 때문에 엄청난
외부 및 내부 fragmentation이 예상되는 군요...

coding standard나, effective c++등의 책을 보면 효율적인 operator overloading 방식에 대한 내용이 있습니다. 책을 참조하고 만드시면 좋겠네요...

_________________________________________________________

nineye's blog

_________________________________________________________

nineye's blog

mirheekl의 이미지


연산자 재정의를 하시더라도
*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?

--

pursy의 이미지

nineye님의 글 감사드립니다.

말씀하신 책 참고하겠습니다. ^^*

mirheekl님의 글도 감사드립니다.

현재 수정하려는 클래스에서 operator의 사용목적은

포인터의 덧셈이 아닌 클래스 내부 double형 포인터의 번지가 아닌 값을 더하려고 하는 거구요.

클래스 초기화시 이 double형 포인터의 크기는 가변적으로 변하게 생성자를 만든겁니다. ^^*

이게 좀 애매모호한 부분이 있네요. ^^;

댓글 달기

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