c++ 소멸자 관련 질문

//여기에 코드를 입력하세요
#include <iostream>

class Point {
public:
    char * name_;
    int age_;
    Point(){};
    Point(char * name,int age) {
        name_ = new char[strlen(name)+1];
        strcpy(name_,name);
        age_=age;
    }

    Point(const Point &p) {
        name_ = new char[strlen(p.name_)+1];
        strcpy(name_,p.name_);
        age_=p.age_;
    }

    ~Point(){
        std::cout<<b<<"start"<<std::endl;
        delete [] name_;
        std::cout<<b++<<"end"<<std::endl;
    }
};

int main(void)
{
    Point p1("C++",20);
    Point p2=p1;
    //Point * p3 = &p1;
    Point & p4 = p1;

    char * name1 = "hello";
    char *& name2 = name1;





    std::cout<<"----------------------------"<<std::endl;


    std::cout<<p1.name_<<std::endl;
    std::cout<<p2.name_<<std::endl;
    //std::cout<<(p3->name_)<<std::endl;
    std::cout<<p4.name_<<std::endl;


    std::cout<<"----------------------------"<<std::endl;
    //p3->name_ = "Hello";


    std::cout<<p1.name_<<std::endl;
    std::cout<<p2.name_<<std::endl;
    //std::cout<<(p3->name_)<<std::endl;
    std::cout<<p4.name_<<std::endl;


    std::cout<<"----------------------------"<<std::endl;
    p4.name_ = "World";


    std::cout<<p1.name_<<std::endl;
    std::cout<<p2.name_<<std::endl;
    //std::cout<<(p3->name_)<<std::endl;
    std::cout<<p4.name_<<std::endl;

    std::cout<<"----------------------------"<<std::endl;
    std::cout<<&name1<<std::endl;
    std::cout<<&name2<<std::endl;
    return 0;
}

자바를 하다가 c++을 공부하고 있는 사람입니다. 책을 통해서 공부를 하다가 궁금한 점이 생겨서 코드를 짰는데, p3와 p4에 의해 런타임 에러가 나는것 같습니다. 포인터 변수와 참조 변수도 프로그램이 끝날때 소멸자가 호출이 되서 동적할당된 메모리를 찾지 못해 에러가 나는건가요?? 아니면 다른 이유가 있는지 궁금합니다. 소멸자안의 출력문은 start1end1start2 입니다. 아니면 코드를 잘못 작성한걸까요??

1답변

  • 자바에는 가비지 컬렉터가 있습니다. 이 가비지 컬렉터가 있어서 메모리 오류는 거의 발생하지 않는 것이 자바의 장점입니다. 또한 문법적인 포인터가 없어서 메모리를 직접 핸들링 할 수 없다는 것도 안정적인 서비스 개발을 위해 한몫하고 있습니다.

    c++ 에서는 가비지 컬렉터가 없으므로 메모리 사용을 주의깊게 해야 합니다.

    자바 개발자가 c/c++ 을 잘 다루려면 메모리 사용은 정말 주의깊게 사용해야 합니다. 많은 학습이 필요할 수도 있습니다.

    간단히 팁을 드리면 c++에서는 char * 대신 string 을 사용하고 new, delete 대신 스마트 포인터를 사용하세요.

    자료구조는 stl을 사용하세요.

    오류의 답만 간단히 말씀드리면...

    질문의 코드에서 p4.name_ = "World"; 와 같이 새로운 곳의 주소를 대입한 모양이 되었습니다.

    name_ = new char[strlen(name)+1]; 의 메모리 주소값이 아니라는 겁니다.

    확인을 위해

    main 함수에 아래와 같이 name_ 주소를 백업하고 return 전에 다시 복원해줍니다.

    Point & p4 = p1;
    char *temp = p1.name_;    // name_ 주소를 백업
    ...
    ...
    p1.name_ = temp;
    return 0;
    
    

    이렇게 하면 segment fault 는 발생하지 않을겁니다.

ᕕ( ᐛ )ᕗ
로그인이 필요합니다

작성한 답변에 다른 개발자들이 댓글을 작성하거나 댓글에 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.