2011-06-14 1 views
2

나는 다음과 같은 문제가 있습니다의 내부 저장 : 벡터 복사 개체 수 std 않는 방법

void add(){ 
    cRow Row(); 
    Row.add("Column", "Value"); 
    std::vector<cRow> mRows; 
    mRows.push_back(Row); 
} 

cRow::cRow(): mCol(NULL), mVal(NULL) { 
} 

cRow::add(const char* Col, const char* Val){ 
    mCol = strdup(Col); 
    mVal = strdup(Val); 
} 

cRow::~cRow(){ 
    free(mCol); 
    free(mVal); 
} 

벡터에 로컬 변수 행을 추가 한 후, 소멸자가 해당 행에 대한라고하며 문자열이 해제됩니다 .

분명히 벡터에 저장된 행의 문자열에 대한 포인터가 해제됩니다. 로컬 범위를 벗어난 후 행에 액세스하면 segfault가 발생합니다.

행의 덤프 보이는 추천 호출 후 :

| (null) | (null) | 
----------------------------------------------------- 
| (null)| (null) | 
| LastContainerUpdatePropagation| 1307967498 | 
------------------------ END ------------------------ 

3 이후 전화 :

| (null) | (null) | 
----------------------------------------------------- 
| (null)| (null) | 
| (null)| (null) | 
| LastSystemUpdatePropagation| 1307967498 | 
------------------------ END ------------------------ 

및 새 행을 추가하지 않고 완전히 범위를 떠난 후, 모든 행이 해제되었습니다 .

이제 내 질문 : 어떻게 표준 : 벡터 복사 개체가 있습니까? 포인터를 문자열에 보관하거나 다른 공간에 복사하려면 어떻게해야합니까?

대단히 감사합니다!

+1

'cRow Row()'는 변수를 선언하지 않고 함수를 선언합니다. 게시 한 코드는 실제가 아니며 컴파일도되지 않습니다. 제발, 실제 코드를 게시하십시오. – AnT

+0

두 단어 : [Rule of Three] (http://en.wikipedia.org/wiki/Rule_of_three_ (C % 2B % 2B_programming)) –

+0

그건 세 단어입니다. – bdonlan

답변

9

std::vector은 개체를 복사 할 때 copy constructor을 사용합니다. 복사 생성자를 정의하지 않았기 때문에 모든 구성원을 반복적으로 복사하는 implicit C++ copy constructor을 사용합니다. 메모리를 수동으로 관리하고 있기 때문에 충분하지 않습니다.

직접 복사 생성자를 정의하거나 std::string과 같은 것을 사용해야합니다. 복사하면 올바른 작업이 수행됩니다.

좋은 연습의 문제로서, 사소한 소멸자가있는 클래스에는 정확하게이 이유 때문에 복사 생성자와 복사 할당 연산자가 있어야합니다 (이 코드는 rule of three). 복사 생성자가 뜻하지 않은 경우 (예 : ostream과 같은 경우) 우발적 인 복사를 방지하기 위해 복사 생성자를 비공개로 만들어야합니다.

+1

"non-trivial class"를 "class" non-trivial constructor을 사용하여 "- 클래스는 충분하고 절대적인 복사 생성자를 사용합니다. –

+1

"* 좋은 연습 문제로서, 평범하지 않은 클래스에는 복사 생성자가 있어야합니다. *"나는이 모든 것에 전적으로 동의하지 않습니다. 대다수의 시간 동안 암시 적으로 정의 된 복사 생성자는 C-with-classes보다는 C++을 사용한다고 가정하고 잘 작성 될 것이고 자신의 글을 작성하는 것은 오류의 가능성을 소개 할 것입니다. – ildjarn

+1

@ildjarn : 바로 그렇습니다. 하위 수준 클래스 (원시 형식과 인터페이스하는 클래스)에는 일반적으로 명시적인 복사 생성자 등이 있지만 일반적으로 상위 수준 클래스는 명시 적으로 정의 된 복사 생성자를 필요로하지 않습니다. – AnT

2

std::vector은 복사 생성자를 사용하여 요소를 초기화합니다. 당신이 명시 적으로 작성하지 않은 경우, 컴파일러는 하나를 제공하지만, 당신은 메모리 관리를하고있다, 당신이 중 하나를해야합니다,

  1. 는 복사 생성자를 제공 할당 연산자 및 소멸자
  2. 합니다 ( Rule of Three 참조) 복사
  3. RAII을 사용하고 단일 값에 대한 모든 메모리 관리를 처리하는 작은 래퍼를 만들고 cRow 클래스에서 필요한만큼 많은 수를 사용합니다 (적절한 복사 생성자, 복사 할당 연산자 및 소멸자를 제공해야합니다. 귀하의 RAII 컨테이너 용).
  4. 메모리를 처리하는 유형을 사용하십시오. 예를 들어 const char*을 사용하고 있으며 메모리 관리를 처리 할 std::string으로 바꿀 수 있습니다.

참고 :은 3 가지 기능 중 사용자 지정 버전을 작성하지 않아도됩니다.