PGR21.com
이전 질문 게시판은 새 글 쓰기를 막았습니다. [질문 게시판]을 이용바랍니다.
Date 2009/09/17 01:58:07
Name EZrock
File #1 SerialTest.cpp (3.2 KB), Download : 25
File #2 InCap2.cpp (3.1 KB), Download : 15
Subject C++ STL중 Vector에 관련한 질문입니다. - 약간 수정하였습니다. -
저도 학년이 학년인만큼 어지간하면 혼자 해결할려고 했지만 이건 도저히 혼자 해결이 안되네요.

제가 해결할려는 문제는 이렇습니다.

크기가 작은 클래스가 있고

그 작은 클래스의 객체를 담는 큰 클래스가 있습니다. 이 큰 클래스의  private 멤버로는 작은 클래스의 객체를 원소로 삼는 벡터가 있습니다.

class a {...};
class b {
    vector<a> b1;
public:
...
   vector<a> getVector() {return b1;}
};

구조가 대충 이렇습니다.

저는 b클래스의 객체를 원소로 삼는 벡터를 객체 직렬화를 이용해서 read write하고 있는데

write하고 read까진 잘 되는데

클래스 b의 private멤버인 vector b1을 리턴받아서 다른 클래스의 함수 같은 곳에서 사용하고자 합니다.

vector<a> b2 = b.getVector(); // vector 연산의 경우 = 이 override되어 있습니다.
for(int i = 0l i < b2.size(); i++) {
     a a1 = b2[i];
    ...
}

이런식으로 이용을 하는데 문제는 이런식의 프로그램을 하고 나면 꼭 종료시에 dbgdel.cpp란 파일에서  asserte가 걸립니다.

여러방면으로 찾아보니까 swallow copy가 되서 메모리가 제대로 지워지지 않았다...

이런식의 메모리 관련 문제로 글이 뜨던데 vector의 경우에는 자동으로 종료시에 할당해제가 되기 때문에 제가 딱히 어떻게 해결할 수 없어서 이렇게 질문을 올립니다.

제가 직면하고 있는 문제점의 정체와 해결 방법을 알려주셨으면 합니다. 약간 급한 문제 입니다.

--------------------------------------------------------------------------------------------

약간 수정했는데 이번에는 직접적으로 벡터를 리턴 받는것이 아니고 인덱스를 줘서 그 인덱스에 있는 원소를 받아오게 하였습니다.

그런데 이렇게 했는데도 dbgdel.cpp에서 _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockuse));

이 문장에서 계속 오류가 발생합니다.

그렇기 때문에 직접 봐주셨으면 하고 이렇게 파일을 올립니다.

프로젝트를 올려서 바로 사용하시게끔 만들려 했는데 php관련 파일은 올릴수 없다고 해서 소스만 따로 올립니다.

1번이 첫번째 문제가 발생한 파일이고

2번째 파일은 미리 생성된 객체 직렬화 된 파일을 똑같은 클래스에서 ifstream을 이용해 읽은후에 출력하게끔 했는데 전혀 작동하지 않고 있습니다.

정말 미칠듯한 답답함에 소스를 올립니다.

객체직렬화 된 파일은 1번파일을 컴파일 후 실행하시면 생성 됩니다.

통합규정 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 04:22
수정 아이콘
와 프로그래밍이다~ 컴공이신가?
이런 질문들 넘 좋아요 //
힘은 되주지 못해 죄송 ㅠ_ㅠ
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 클래스에 대해서는 이와 같은 문제를 해결하도록 구현하였을 겁니다.
목록 삭게로! 맨위로
번호 제목 이름 날짜 조회
64113 원피스 질문... [13] KnightBaran.K2111 09/09/17 2111
64112 포도씨를 심으면 포도가 나나요? [9] Haru23319 09/09/17 23319
64111 앱스토어 질문입니다. [4] amoelsol1690 09/09/17 1690
64110 대상 포진이란 병에 걸렸는데요 [8] 2ndEpi.3891 09/09/17 3891
64109 오랜만에 와우를 하려니 적응이 안되네요 [9] 탄야2151 09/09/17 2151
64108 강아지 사료 내츄럴발란스 살 수 있는 인터넷 쇼핑몰이 있나요? [2] Zakk Wylde2513 09/09/17 2513
64107 휴대폰 할부금에 대해 질문드려요 [3] GoThree2587 09/09/17 2587
64106 C# 원론적인 질문입니다.. [7] 특수알고리즘2320 09/09/17 2320
64105 C++ STL중 Vector에 관련한 질문입니다. - 약간 수정하였습니다. - [5] EZrock2938 09/09/17 2938
64104 발더스 게이트 트릴로지는 어떤거죠? [5] 스푼 카스텔9300 09/09/17 9300
64102 다이어트 질문입니다 [3] 꽃비1697 09/09/17 1697
64100 팔굽혀펴기 질문입니다. [7] wook985650 09/09/17 5650
64099 노래방에서 키를 낮추면 음이 얼마나 내려가나요? [7] 논트루마14256 09/09/17 14256
64098 엠넷 DRM 제거 관련 [6] KyRiE8804 09/09/17 8804
64096 [운동] 구토를 할때까지 음주를 할때 근육에 미치는 악영향은? [7] 육식코끼리2186 09/09/16 2186
64093 이런 질문은 해도 될 지 모르겠지만 [1] 꽃보다질럿2148 09/09/16 2148
64090 남자 사진(패션,옷,헤어)많은 사이트 없나요? [6] EsPoRTSZZang2280 09/09/16 2280
64089 캠코더 질문입니다. [1] 김정환1322 09/09/16 1322
64088 저 병원에대해서 질문좀요.. [3] PoLoman1889 09/09/16 1889
64087 영화 화질(?)에 관한 질문입니다 [1] Luvswear1580 09/09/16 1580
64086 나라사랑카드 질문이요 [4] 무쇠다리2336 09/09/16 2336
64085 g1 마우스 마지막으로 질문드립니다.. [15] 비야레알1678 09/09/16 1678
64084 처음 알게 된 이성과의 2시간 출퇴근. [25] 마루가람2648 09/09/16 2648
목록 이전 다음
댓글

+ : 최근 6시간내에 달린 댓글
+ : 최근 12시간내에 달린 댓글
맨 위로