[C++] 이 소스의 문제는 대체 무엇일까요?

greathero의 이미지

컴파일러에 걸리는 에러 및 워닝은 없고요.
실행하면 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하려고 해서 그런듯

greathero의 이미지

Point(int x, int y, char* name): mx(x), my(y) { 
		int len = strlen(name) + 1; // NULL 문자까지
		mname = new char[len];
		strcpy_s(mname, len, 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; } 

이렇게 바꾸어봤는데도 똑같은 에러창이 뜨네요ㅠㅠ
왜 제대로 소멸이 안되는걸까요?

익명 사용자의 이미지

setName()에서 또다른 리터럴을 그냥 포인팅하고 있죠 ^^

greathero의 이미지

일단은 아래와 같이 임시방편적으로 떼워놓았는데 더 좋은 방안이 있을까요?

void setName() 
{ 
	char* tmpChar = "GOAL"; // 포인트의 이름을 임의로 GOAL이라고 변경 
	int len = strlen(tmpChar) + 1;
	mname = new char[len];
	strcpy_s(mname, len, tmpChar); 
} 
익명 사용자의 이미지

제일 좋은 방법은 std::string을 사용하는 겁니다. ^^

만...

c string을 공부중인거 같으니까 관련으로 얘기한다면
mname은 이미 생성자에서 메모리를 할당받았으니까
new를 다시 할 필요는 없어 보입니다.
굳이 new를 다시 하고 싶다면 기존의 것은 delete를 해줘야겠죠.

new와 delete의 개수가 안맞는다는건 곧 메모리 누수입니다. ^^

greathero의 이미지

궁금;;;

익명 사용자의 이미지

위 코드에서 new하고 있는 라인을 지우면 됩니다.
현재 mname의 사이즈가 복사될 사이즈보다 크기 때문에 아무런 문제가 없죠.

이렇게 칼같이 그 사이즈를 딱딱 잡아주고 싶다면
위 코드에서 new하고 있는 라인 바로 위에
delete[] nmame;
넣어줘야 메모리 누수가 생기지 않습니다.

참고로 보통 c string을 사용할 때는
char 배열을 적당히 넉넉히 잡아놓고
strcpy로 값을 넣어줍니다.

앞에서도 얘기했듯이 제일 좋은 방법은
std::string을 사용하는 거구요.

댓글 달기

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 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.