[C++] 이 소스의 문제는 대체 무엇일까요?
컴파일러에 걸리는 에러 및 워닝은 없고요.
실행하면 OUTPUT은 다 뽑아내고 갑자기 에러창이 뜨면서 "중단"버튼을 눌러서 종료해야 하네요ㅠ
이 소스는 복사 생성자를 통해 깊은 복사를 하는 코드를 간단히 구현해본건데요.
무슨 문제가 있는걸까요? 한번 봐주세요ㅠ
----------------------------------------------------------------------------------
#include
#include
using namespace std;
class Point {
public:
Point(int x, int y, char* name): mx(x), my(y), mname(name) { }
Point(const Point& rhs): mx(rhs.mx), my(rhs.my) {
int len = strlen(rhs.mname) + 1; // NULL 문자까지
mname = new char[len];
strcpy_s(mname, len, rhs.mname);
}
~Point() { delete[] mname; }
void output() { cout << "x: " << mx << endl; cout << "y: " << my << endl; cout << "name: " << mname << endl; }
void setName() { mname = "GOAL"; } // 포인트의 이름을 임의로 GOAL이라고 변경
private:
int mx;
int my;
char* mname;
};
int main(int argc, char** argv) {
Point A(10, 20, "START");
Point B(A);
A.output();
B.output();
A.setName();
A.output();
B.output();
return 0;
}
복사생성자 말고 그냥 생성자로 생성될때 문자열이
복사생성자 말고 그냥 생성자로 생성될때
문자열이 new로 생성되는게 아니고
소스코드(프로세스의 텍스트영역)에 있는 스트링리터럴을 포인팅할 뿐인데....
그걸 소멸자에서 delete하려고 해서 그런듯
그래서 이렇게 바꾸어봤는데요
이렇게 바꾸어봤는데도 똑같은 에러창이 뜨네요ㅠㅠ
왜 제대로 소멸이 안되는걸까요?
setName()에서 또다른 리터럴을 그냥 포인팅하고
setName()에서 또다른 리터럴을 그냥 포인팅하고 있죠 ^^
아하. 그렇군요;;;
일단은 아래와 같이 임시방편적으로 떼워놓았는데 더 좋은 방안이 있을까요?
제일 좋은 방법은 std::string을 사용하는
제일 좋은 방법은 std::string을 사용하는 겁니다. ^^
만...
c string을 공부중인거 같으니까 관련으로 얘기한다면
mname은 이미 생성자에서 메모리를 할당받았으니까
new를 다시 할 필요는 없어 보입니다.
굳이 new를 다시 하고 싶다면 기존의 것은 delete를 해줘야겠죠.
new와 delete의 개수가 안맞는다는건 곧 메모리 누수입니다. ^^
굳이 new를 다시 안해도 된다면 어떻게 하면 되나요?
궁금;;;
그냥...
위 코드에서 new하고 있는 라인을 지우면 됩니다.
현재 mname의 사이즈가 복사될 사이즈보다 크기 때문에 아무런 문제가 없죠.
이렇게 칼같이 그 사이즈를 딱딱 잡아주고 싶다면
위 코드에서 new하고 있는 라인 바로 위에
delete[] nmame;
넣어줘야 메모리 누수가 생기지 않습니다.
참고로 보통 c string을 사용할 때는
char 배열을 적당히 넉넉히 잡아놓고
strcpy로 값을 넣어줍니다.
앞에서도 얘기했듯이 제일 좋은 방법은
std::string을 사용하는 거구요.
댓글 달기