:: 게시판
:: 이전 게시판
|
이전 질문 게시판은 새 글 쓰기를 막았습니다. [질문 게시판]을 이용바랍니다.
통합규정 1.3 이용안내 인용"Pgr은 '명문화된 삭제규정'이 반드시 필요하지 않은 분을 환영합니다.법 없이도 사는 사람, 남에게 상처를 주지 않으면서 같이 이야기 나눌 수 있는 분이면 좋겠습니다."
09/09/17 02:17
음..아직 copy에 대한 개념이 제대로 안잡혀 있으신 것 같군요;;
swallow copy를 아셨다면 deep copy와 reference counting, 나아가서는 smart_ptr에 대해서까지 알아보시면 좋을 겁니다. 각설하고, EZRock님께서 격고 있는 문제는 a라는 class의 copy 연산자를 제대로 구현하지 않아서 발생하는 듯 합니다. 에러메세지를 봐야 알겠지만, a class에 operator= 에 대한 정의가 없다면 이럴 가능성이 높은 것 같네요. 객체를 = 와 같은 연산자로 copy construct하는 코드가 없기 때문에 b2[i]의 reference만 a1에 할당이 됩니다. 이렇게 되면 a1이 지역 변수이기 때문에 scope을 벗어나면서 메모리가 꼬이게 되겠죠. 제대로 구현하려면 1. operator=를 override해서 a의 속성값만을 복사하도록한다. 2. copy constructor를 구현한다. 3. copy method를 구현해서 사용한다. 4. vector에 a의 pointer를 넣어서 관리한다. 5. .. 6. .. 등등 여러 방법이 있겠습니다. 아무튼 getVector method도 그렇고 별로 바람직한 코드는 아니네요.
09/09/17 02:44
제가 getVector를 저렇게 만든 이유가 있습니다.
하나는 vector간 = 연산에 대한 overloading이 되어 있습니다.(위의 override는 제가 착각한것입니다;) 그렇기 때문에 vector 객체 자체를 리턴 받아서 대입시켜도 문제가 없다고 판단했기 때문에 저렇게 했습니다. 근데 저 같은 경우에는 지금 객체 직렬화 과정에서 좀 심하게 꼬이나 봅니다;;
09/09/17 09:27
열심히 댓글 달려고 했다가 날카로운 빅뱅님의 리플에 1표입니다! 흐흐-
한마디만 더하자면 getVector()가 바람직하지 않은 다른 이유는 벡터를 통째로 복사하므로 메모리&시간 자원을 많이 먹는다는 겁니다. 복사가 꼭 필요한 경우가 아니라면 pointer나 reference를 이용하는 게 좋죠.
09/09/17 10:04
우왕...파일 받아서 실험해봤는데 정말 오묘한 문제였습니다. 미칠듯한 답답하심이 이해가 갈정도..
문제의 원인은 string 클래스의 메모리 내용 자체를 파일에 그대로 썼다가 읽으려 하는 것입니다. string 클래스는 기본적으로 가변 문자열을 담는 클래스입니다. 즉 내부에서 동적 할당 등이 일어고 포인터를 사용할 수밖에 없죠. 그러나 명색이 C++ 표준 클래스이니만큼 빅뱅님이 말씀하신 shallow copy 문제를 내부적으로 해결합니다. 대입문을 사용하면 아예 deep copy를 해주던 reference counting을 하던.. 따라서 string A1이 메모리 M1을 가리키고 있을 때 string A2에 대입문으로 한번 복사한다면 메모리 M2를 할당하고 메모리 M1과 동일한 내용을 채워넣어주거나 (shallow copy) 메모리 M1을 string A1, A2 2개의 객체가 동시에 참조하고 있다는 정보를 저장합니다. (reference counting) 그런데 만일 대입문이 아니라 string A1이 담긴 메모리 내용 자체를 파일에 그대로 썼다가 string A2객체에 읽으면 어떻게 될까요? A2에는 정확히 A1과 같은 정보가 들어가게 되어 똑같이 메모리 M1을 참조하게 되고, 대입문이 아니므로 deep copy 혹은 reference counting 동작이 일어나지 않게 되어 새로운 메모리도 할당이 안되고 혹은 참조 객체가 하나 늘어났다는 정보도 생기지 않게 됩니다. 이 상태에서 프로그램이 끝나고 메모리를 해제하게 되면 A1이 해제될 때 M1을 해제하였는데 A2가 M1을 해제하려니 이미 해제된 메모리를 해제하려는 에러가 생기게 되는 거죠. 즉, string 클래스에는 내부적으로 문자열 내용만이 아니라 관리를 위한 추가정보들이 있는데 그것들을 그대로 쓰고 다시 이용하는 데서 문제가 생기는 겁니다. string을 파일에 읽고 쓸 때는 문자열 내용만 다루도록 해줘야 하죠. 아마 표준 IO 스트림에 << >> 연산자로 파일 입출력이 되게 하였을 텐데, string 클래스에 대해서는 이와 같은 문제를 해결하도록 구현하였을 겁니다.
|