해결된 질문
작성
·
247
·
수정됨
0
안녕하세요. 선생님
이동 생성자 강의 내용 중 질문이 있습니다. (아래 코드 참고)
delete pnData를 하면, 포인터 변수가 해제되어
pnData = rhs.pnData;를 실행할 수 없는 것이 아닌지 궁금합니다. 실재로는 포인터 값은 그대로고, 가리키는 값(int 0)만 삭제되는 것인가요?
포인터 값은 놔두고 가리키는 값만 없애는 문법은 어떻게 되나요? delete를 안하고, pnData = nullptr; 로만 수정해도 됬을 것 같습니다.
class TestData
{
public:
TestData(){
pnData = new int(0);
}
...
TestData(TestData&& rhs) noexcept{
delete pnData;
pnData = rhs.pnData;
rhs.pnData = nullptr;
}
...
TestData& operator=(TestData&& rhs) noexcept{
delete pnData;
pnData = rhs.pnData;
rhs.pnData = nullptr;
}
}
답변 3
1
delete pnData; 연산을 수행한다고 하더라도 포인터 변수 자체가 사용하는 메모리는 사라지지 않습니다.
예를 들어
char *pszData = nullptr;
pszData = (char*)malloc(128);
...
free(pszData);
같은 코드를 수행하더라도 pszData 변수가 사용하는 메모리가 해제되지는 않습니다. new나 delete도 동일합니다.
0
포인터를 멤버로 갖는 객체가 소멸하면 포인터 멤버도 소멸되는 것은 당연합니다.(클래스)
-> 포인터 메모리 자체를 삭제하는 방법은 객체 소멸 방법 밖에 없나요? free 함수등으로 가능한가요?
Q. 제일 궁금한 내용은 delete 연산(포인터가 가리키는 값을 삭제)한 이후, 어떻게 rhs.pnData 값을 대입할 수 있는지입니다.
즉 delete 연산을 하면, 포인터 메모리 자체는 살아있는지 여부입니다.
<강의 코드>
delete pnData;
pnData = rhs.pnData;
0
우선 pnData 는 int* 멤버인 것으로 가정하고 답변하겠습니다.
포인터는 포인터 자체와 포인터가 가리키는 대상으로 구별해 생각해야 하겠습니다. delete pnData; 라는 코드가 수행되면 포인터가 가리키는 대상 메모리는 해제됩니다. 그렇다고 포인터 값이 달라지는 것은 아닙니다. 가령 내 휴대폰에 저장된 친구 길동이의 전화번호는 길동이가 휴대폰 번호를 바꾼다 하더라도 알아서 바뀌지 않습니다. 포인터 변수는 그저 주소를 저장하기 위한 용도로 사용되는 변수형식 입니다. 그 속에 저장된 주소의 메모리가 할당되어 사용할 수 있는지 여부와 아무런 관련이 없습니다.
pnData = rhs.pnData; 코드는 r-value에 저장된 주소를 pnData에 저장하는 것입니다. 단순히 주소만 저장할 뿐 대상 메모리를 복사하지는 않습니다.
끝으로 포인터 값은 두고 가리키는 대상(값이 아니라 메모리)를 삭제하는 방법은 delete 연산을 하는 것입니다. pnData = nullptr; 같은 코드를 수행하면 동적 할당된 메모리가 해제되지 않고 주소 값을 잃어버리기 되어 메모리 누수가 발생합니다.
포인터에 대해 다시 복습할 것을 권합니다. 감사합니다. 😄
자세히 설명해주셔서 이해가 되었습니다.
감사합니다.
그럼 혹시 pnData 주소값을 가리키는 포인터 자체도 메모리일텐데, 해당 포인터의 메모리를 해제할수 있는 방법도 있나요?
포인터가 가리키는 값만 해제하면 포인터 자체는 남아있을것 같아서요.
이해되었습니다.
감사합니다!!😁