c++ 임시객체 주소값과 생성자, 소멸자에 대한 질문
글쓴이: wans038 / 작성시간: 월, 2016/02/08 - 4:48오후
오늘 설날이군요, 재미있게 보내시길 바랍니다.
우선 질문부터 드리겠습니다.
class Point { public: int xpos, ypos; public: Point(int x = 0, int y = 0) : xpos(x), ypos(y) { cout << "포인트 생성자 " << this << endl; } friend ostream& operator<<(ostream& os, const Point& pos); ~Point() { cout << "포인트 소멸자 " << this << endl; } void Adress(void) { cout << "어드레스 " << this << endl; } }; // 메인 Point* ptr = &Point(500, 600); cout << ptr->xpos << endl;
포인트 생성자 (주소값0)
포인트 소멸자 (주소값0)
500
이 출력 됩니다. 그런데 이해가 가지 않습니다. 어떻게 객체가 소멸됬는데 그 가르키는 객체의 xpos가 정상출력이 될 수 있는건가요?
그리고
Point& ref = Point(500, 600);
포인트 생성자 (주소값0)
500
포인트 소멸자 (주소값0)
...임시객체의 주소값을 저장하는것과 참조하는것 차이가 내부적으로 무슨 차이가 있는 걸까요? 컴파일러(?) 가 임시객체 주소값을 가르키면 바로 생성자 다음 소멸자를 호출하도록 명령하는건가요?
그리고 한가지더 궁금한데 있는데요.
Point* pArr[2] = { &Point(100, 150), &Point(200, 250) }; Point** ppArr = pArr; Point*& pRef = ppArr[0]; cout << pRef->xpos;
이 코드는 이상하네요... 많이요. 왜 그러는지 도저히...감을 못잡겠습니다.
생성자 또는 소멸자에 cout 나 cin이 있으면 100이 잘 출력되고요...
만약 생성자, 소멸자 둘다 cout나 cin이 없으면 쓰레기 값이 나오네요...
생성자, 소멸자에 this 키워드나 abs함수 등 만 있어도 쓰레기값이 나오네요...
Point(int x = 0, int y = 0) : xpos(x), ypos(y) { // cout << "포인트 생성자 " << this << endl; } ~Point() { // cout << "포인트 소멸자 " << this << endl; }
긴 글읽어주셔서 감사합니다.
Forums:
참고해보세요.
테스트해보니. 함수안에서만 값이 변경되지 않았습니다.
_msize(ptr); 로 확인하니. 동적 메모리 할당은 아니었습니다. (윈도우에서만 잘 됩니다.)
sizeof(ptr); 로 확인하니. 4바이트로 표시됩니다.
지역 변수에 주소가 할당된 상황으로 보입니다.
정확한 내용은 C언어 책을 확인하거나. 전문 교육기관에 문의해보시기 바랍니다.
참고용으로 관련된 주소를 올려봅니다.
malloc
http://www.cplusplus.com/reference/cstdlib/malloc/
정적 메모리 할당
https://ko.wikipedia.org/wiki/%EC%A0%95%EC%A0%81_%EB%A9%94%EB%AA%A8%EB%A6%AC_%ED%95%A0%EB%8B%B9
new 연산자 실패
http://erde.tistory.com/102
new 연산자 예외처리
http://blog.naver.com/is1040/220081397142
Placement new( new 연산자 사용시 메모리 지정 하기!! )
http://blog.naver.com/yooncj66/130161721004
new 연산자를 사용한 동적 메모리 할당 실패시 예외 처리
http://kuaaan.tistory.com/123
new 연산자
https://msdn.microsoft.com/ko-KR/library/windows/apps/xaml/ye4tfyby(v=vs.100).aspx
new 연산자로 메모리 할당 받을 때 size 가 0 이면 어떻게 되나요?
https://kldp.org/node/153915
상수(const)의 정의가 궁금합니다...
https://kldp.org/node/144933
정적변수 ( static 변수 ) 와 필드의 차이점이 뭘까요?
https://kldp.org/node/151445
---------------------------------------------
이중 포인터와 구조체 이중 포인터 사용하는 방법 | 개발 정보
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=50&MAEULNO=20&no=919791&ref=919791&page=1
클래스 오퍼레이터 operator []를 배열로 사용하는 방법 ★★★★★ C++
https://kldp.org/node/154423
다중 포인터 배열을 new로 할당 해제하는 방법 연습
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=50&MAEULNO=20&no=963050&ref=963050&page=1
malloc()과 new 배열[] 로 할당된 메모리에 크기 보는 방법 ★★★★★ | 한메일
sizeof 연산자
https://msdn.microsoft.com/ko-kr/library/4s7x1k91.aspx
strlen 과 sizeof 의 차이
http://forum.falinux.com/zbxe/index.php?document_srl=532125&mid=lecture_tip
new로 할당된 개체 수명
https://msdn.microsoft.com/ko-KR/library/windows/apps/64d25ba5(v=vs.120).aspx
malloc()
https://msdn.microsoft.com/ko-kr/library/6ewkz86d.aspx
http://kldp.org/node/153901
http://kldp.org/node/153915
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=50&MAEULNO=20&no=961016&ref=961016&page=1
이중포인터 배열을 new와 delete [] 로 할당 해지하는 방법 - 연습 ★★★★★
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=50&MAEULNO=20&no=962136&ref=962136&page=1
new 연산자를 char* [] 배열에 적용할때
http://blog.naver.com/kyehwan2?Redirect=Log&logNo=10013981548
정적할당과 동적할당
http://hoonspace.tistory.com/entry/메모리-할당
클래스 오퍼레이터 operator []를 배열로 사용하는 방법 ★★★★★ C++
https://kldp.org/node/154423
malloc()과 new 배열[] 로 할당된 메모리에 크기 보는 방법 ★★★★★
http://blog.daum.net/knightofelf/15436
new 메모리에 가로세로크기를 동적으로 할당하는 방법
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=50&MAEULNO=20&no=959907&ref=959907&page=2
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
...
> 어떻게 객체가 소멸됬는데 그 가르키는 객체의 xpos가 정상출력이 될 수 있는건가요?
C/C++은 매우 불친절한 언어라서, "제대로 짰을 때 제대로 된 결과가 나옴"만을 보장합니다.
다시 말해, "틀리게 짰을 때 잘못된 결과가 나옴"을 절대로(!!!) 보장하지 않습니다. 일단 코드를 틀리게 짜는 순간 컴파일러는 무슨 짓이든지 할 수 있고 아무 결과나 나오게 만들 수 있습니다.
아무 결과나 나올 수 있다는 말은 어쩌다가 "올바른(??) 결과"도 나올 수 있다는 뜻입니다. 그렇다고 해서 그 코드가 올바르다는 뜻은 아닙니다.
좀 더 구체적으로 말하자면, 코드에서 소멸자를 불렀기 때문에 해당 포인터가 가리키는 영역은 더 이상 사용할 수 없는 영역이 됩니다.
다시 말해, 더 이상 "이 포인터가 가리키는 주소를 읽으면 원래 값을 읽을 수 있음"을 보장하지 않습니다.
하지만 그렇다고 해서 "이 포인터가 가리키는 주소를 읽으면 원래 값을 읽을 수 없음"을 보장한다는 뜻은 절대로 아닙니다!
잘 생각해 보세요.
프로세스가 운영체제로 부터 메모리 조각 단위로 할당
프로세스가 운영체제로 부터 메모리 조각 단위로 할당 받지 않습니다.
mmap()이라는 시스템 콜로부터 지역변수 및 임시 변수가 저장될 공간을 1차적으로 할당 받습니다.
(mmap()은 컴파일러가 알아서
호출해코드사이에 끼워 줍니다.)그 후 프로세스에서 지역변수와 임시변수등을 해당공간에 할당해주는 건데
해당 임시 변수의 메모리 공간이 운영체제에게 아직 반납 안되어 있으면, 출력이 가능한 겁니다.
만약 객체의 크기를 4KB로 만들고
이런식으로 짜게되면 callee()에서 스택(임시변수가 저장되는 공간)을 반납 한 상태에서
caller가 해당 메모리 공간을 참조하려고 하기 때문에 오류(Segmentation fault)가 날 겁니다.
댓글 달기