동적 할당과 클래스에 대한 질문

익명 사용자의 이미지

class Stack {
private:
	int * _stack;
	int _size;
public:
	Stack(int array[], int size);
	~Stack();
Stack Stack::operator*(int num);
//나머지 함수 생략
};
<cpp>
 
다음과 같은 클래스가 있다 합시다. 그러면 생성자를 만들 때엔,
 
<cpp>
	_stack = new int[MAX_STACK];

다음과 같이 동적 메모리 선언을 하고,
Stack::~Stack() {
delete[] _stack
}

과 같이 소멸자에서 동적 메모리를 해제하는 delete[] 연산자를 삽입하는 것이 일반적이겠죠? 근데 저에게 작은 문제가 생겼습니다ㅠㅠ

Stack Stack::operator*(int num) {
	int new_size = this->_size;
	int array[MAX_STACK] = { 0 };
	for (int i = 0; i < MAX_STACK; i++) {
		if (i < this->_size) {
			array[i] = num * this->_stack[i];
		}
		else {
			array[i] = 0;
		}
	}
 
	return Stack(array, new_size);
}

다음 함수에서 return Stack을 하고 중괄호가 닫힐 때 Stack에 있는 소멸자가 작동해버리고, 그 때 delete[]도 같이 작동해서 _stack에 있는 값들을 참조할 수 없는 문제가 생겨버렸습니다. 실제로 소멸자에 있는 delete[]를 지워버리면 잘 굴러갑니다. 대신 저희 컴퓨터 메모리가 많이 아파할 것 같지만요. 어떻게 코드를 바꾸어야 소멸자 속 delete[]를 유지하면서 프로그램이 정상작동하게 할 수 있을까요?

Stephen Kyoungwon Kim@Google의 이미지

어떻게 보느냐에 따라 다른데, memory buffer의 ownership 문제죠. local stack에 할당되었던 Stack object가 return과 함께 사라지는데, 사라지기 전에 (개념상) return value object에다 적잘한 카피를 해줘서, 그 사라짐이 문제를 일으키지 않았어야 합니다.

하지만, 실제로는 사라지면서 자기가 쥐고 있던 buffer를 날리는데, 임시 return value object에다가는 그냥 shallow copy를 해줘서, return value object의 _stack은 dangling pointer가 됩니다. 다른 말로 이 _stack이 가리키는 버퍼의 ownership을 넘겨주지 않은 거죠.

이 디자인을 유지할 경우 move semantic이 적용될 수 있게끔 rule of five에 따라 적당한 함수들을 추가해 주시는 게 한 방법이고, 아니면 _stack에 raw pointer 대신 unique_ptr을 사용하는 쪽도 고려할 수 있습니다.
https://stackoverflow.com/questions/16711697/is-there-any-use-for-unique-ptr-with-array/16804634

익명 사용자의 이미지

https://kldp.org/node/163145

이 분과 비슷한 종류의 실수를 저지르고 계신 듯.

C++ 객체로 자원 관리를 하려면 생성자+소멸자+복사 생성자+복사 할당 연산자(C++11부터는 +이동 생성자+이동 할당 연산자)를 모두 숙지하고 있어야 합니다.

댓글 달기

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