• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    해결됨

9.11 8분쯤 질문

24.02.09 22:26 작성 24.02.09 22:42 수정 조회수 83

1

#include <iostream>
#include <cassert>
using namespace std;

class MyString {
public:
	char *m_data = nullptr;
	int m_length = 0;

public:
	MyString(const char *source = "") {
		assert(source);	// 받은 문자열이 비어있진 않은가 확인

		m_length = std::strlen(source) + 1;
		m_data = new char[m_length];	// 배열 동적할당

		for (int i = 0; i < m_length; ++i)
			m_data[i] = source[i];

		m_data[m_length - 1] = '\0';
	}

	~MyString() 
	{
		delete[] m_data;
	}

	char* getString() {
		return m_data;
	}

	int getLength() {
		return m_length;
	}
};


int main() {
	MyString hello("Hello");

	cout << (int*)hello.m_data << endl;
	cout << &(hello.m_data) << endl;
	cout << hello.getString() << endl;

	{
		MyString copy = hello;
		cout << (int*)copy.m_data << endl;
		cout << &(copy.m_data) << endl;
		cout << copy.getString() << endl;
	}


	cout << hello.getString() << endl;

	return 0;
}

 

  1. 여기에서 cout << (int*)hello.m_data << endl;cout << &(hello.m_data) << endl; 의 값이 다르게 출력되는 이유가 뭔지 궁금합니다.

int main() {
    char name[] = "jack jack";
 
    cout << (int*)name << endl;
    cout << &name << endl;
}

이렇게 했을 때는 두 주소값이 같게 찍히는데, 위의 경우와 어떻게 다른지 궁금합니다.

 

 

  1. 그리고 main함수에서 scope를 빠져나오고, cout << hello.getString() << endl; 했을 때, 저는 Hello 라고 잘 출력이 되는데, 이건 컴파일러와 다른건가요? (강의 영상 8분 22초에서 보여지는 결과와 다르게 나옵니다.)

스크린샷 2024-02-09 오후 10.26.25.png

답변 1

답변을 작성해보세요.

1

Soobak님의 프로필

Soobak

2024.02.10

안녕하세요, 질문&답변 도우미 Soobak 입니다.

 

질문 1)

: cout << (int*)hello.m_data << endl;m_data 포인터 변수가 가리키는 문자열 데이터의 '실제 시작 주소' 를 출력합니다. 이는 동적으로 할당된 문자 배열 중 첫 번째 문자의 주소 입니다.

반면, cout << &(hello.m_data) << endl;m_data 포인터 변수 자체의 주소를 출력합니다.

즉, MyString 객체 내에 있는 m_data 포인터 변수의 주소와, 이 포인터가 가리키는 메모리 영역(문자 배열)의 주소는 서로 다릅니다.

 

첨부해주신,

int main() {
    char name[] = "jack jack";
 
    cout << (int*)name << endl;
    cout << &name << endl;
}

코드에서, cout << (int*)name << endl; 는 배열의 이름을 통하여 배열의 시작 주소를 출력합니다.
배열의 이름은 배열의 첫 번째 원소를 가리키는 포인터와 호환이 되는 형태이며, 배열의 시작 주소와 같은 값을 가지게 되기 때문에, cout << &name << endl; 의 출력 결과와 같게 되는 것입니다.

 

배열과 포인터는 서로 관련되어 있지만, 기본적으로는 다른 개념임을 이해하시면 도움이 되실 것 같습니다.
포인터는 메모리 주소를 저장하는 '변수' 입니다.

첫 번째 경우에서는 메모리에 저장된 데이터의 주소와 그 데이터를 가리키는 포인터 변수의 주소를 출력한 것이고, 두 번째 경우에서는 배열의 시작 주소를 두 가지 방식으로 출력한 것입니다.

 

 

질문 2)
: 잘 출력되는 것 '처럼' 보이지만, 실제로는 이미 해제된 메모리에 접근하여 남아있는 값을 출력한 것입니다.
말씀하신 것 처럼, 프로그램이 이미 해제된 메모리에 접근하는 것의 결과는 컴파일러/환경 마다 다르게 작동합니다. 따라서, 메모리의 관리는 특히 중요하게 다루어야 합니다.