해결된 질문
작성
·
155
·
수정됨
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;
}
여기에서 cout << (int*)hello.m_data << endl;
과 cout << &(hello.m_data) << endl;
의 값이 다르게 출력되는 이유가 뭔지 궁금합니다.
int main() {
char name[] = "jack jack";
cout << (int*)name << endl;
cout << &name << endl;
}
이렇게 했을 때는 두 주소값이 같게 찍히는데, 위의 경우와 어떻게 다른지 궁금합니다.
그리고 main함수에서 scope를 빠져나오고, cout << hello.getString() << endl;
했을 때, 저는 Hello 라고 잘 출력이 되는데, 이건 컴파일러와 다른건가요? (강의 영상 8분 22초에서 보여지는 결과와 다르게 나옵니다.)
답변 1
1
안녕하세요, 질문&답변 도우미 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)
: 잘 출력되는 것 '처럼' 보이지만, 실제로는 이미 해제된 메모리에 접근하여 남아있는 값을 출력한 것입니다.
말씀하신 것 처럼, 프로그램이 이미 해제된 메모리에 접근하는 것의 결과는 컴파일러/환경 마다 다르게 작동합니다. 따라서, 메모리의 관리는 특히 중요하게 다루어야 합니다.