[완료] 인자로 넘긴 클래스의 소멸 시점

moonhalo의 이미지

#include <iostream>   
using namespace std;   
 
class CFoo   
{   
public:   
    CFoo()   
    {   
        mpText = new char[32];   
        strcpy( mpText, "abc" );   
    }   
    ~CFoo()   
    {   
        delete [] mpText;   
        mpText = NULL;   
    }   
 
    char *mpText;   
 
    operator char* ()   
    {   
        return mpText;   
    }   
};   
 
 
void Show( char *pText )   
{   
    cout<<pText<<endl;   
}   
 
 
int main( int argc, char * argv )   
{   
    Show( CFoo() );   
    return 0;   
}  

코드는 간단하고, 잘 돌아갑니다.
궁금한게 Show(CFoo());에서 생성한 CFoo개체가 소멸되는 시점입니다. 정확히는 소멸자가 불리는 시점이죠.

제가 생각한건 이랬습니다.
(1) Show(CFoo()); 에서 CFoo 임시 개체 생성
(2) CFoo::operator char* () 호출되서 Show()에 인자로 넘길 pText에 대입
(3) (1)에서 생성된 임시 개체 소멸 : 소멸자 호출
(4) pText를 인자로 Show() 호출.

헌데, 실제로는 Show() 함수가 끝난다음에 소멸자가 호출되네요.
즉, Show()호출할 때 생성되서 동작하는 동안 임시 개체가 계속 살아 있다는 건데...
(1)의 임시 개체는 실제로는 인자가 아니니까 함수 호출전에 소멸될거라 생각했는데 말이죠.
임시 개체도 함수 종료후 소멸되는게 C++ 스펙인가요?
인자에 대해 생성과 파괴 순서가 어떻게 되는지 알려주시길 부탁드립니다. ^^

M.W.Park의 이미지

스택(activation record)에 생성된 것은 스택이 없어질 때 같이 없어지는 것으로 배웠습니다.

-----
오늘 의 취미는 끝없는, 끝없는 인내다. 1973 法頂

-----
오늘 의 취미는 끝없는, 끝없는 인내다. 1973 法頂

moonhalo의 이미지

감사합니다. 위코드에서 생성자로 생성된 객체도 스택에 저장된다고 생각하니 이해가 되네요. ^^

buelgsk8er의 이미지

임시객체는 그것을 생성하고 있는 full-expression을 평가하는 마지막 단계에서 삭제된다고 합니다.

참고: http://stackoverflow.com/questions/1837092/c-destruction-of-temporary-object-in-an-expression

(아마도) C++ 표준 문서 인용:


12.2 Temporary objects, clause 3: "Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created."

1.9 Program execution, clause 12: "A full-expression is an expression that is not a subexpression of another expression."

그러니 Show( CFoo() ) 라는 표현식이 끝날 때 삭제되겠지요. 저 문장 다음에 적당히 다른 문장 넣고 디버깅 문자열 찍거나 디버거로 돌려보면 새로 추가한 문장이 시작되기 전에 임시객체의 소멸자가 호출되는 것을 확인하실 수 있을 듯.

fghj1의 이미지

buelgsk8er님 말이 맞는 듯합니다. 추가적으로 본문의 소스를 살펴보니 만약, 작성자님의 생각대로 아래 순서대로 된다면,

(1) Show(CFoo()); 에서 CFoo 임시 개체 생성
(2) CFoo::operator char* () 호출되서 Show()에 인자로 넘길 pText에 대입
(3) (1)에서 생성된 임시 개체 소멸 : 소멸자 호출
(4) pText를 인자로 Show() 호출.

문제가 생길 것 같습니다. 3번 과정에서 CFoo가 소멸되어 버렸다면, CFoo::mpText에 할당된 자원도 같이 해제될테니 4번 과정에서 이미 해제된 자원에 접근하려고 하니 문제가 생기겠죠.

댓글 달기

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