2010-02-22 5 views
3

이상한 문제가 있습니다. 객체를 푸시 (push)하고자하는 벡터가 있습니다.벡터에 push_back

vector<DEMData>* dems = new vector<DEMData>(); 
DEMData* demData = new DEMData(); 
// Build DEMDATA 

dems->push_back(*demData); 

벡터에 몇 백 개의 DEMData 객체가 있습니다. 문제는이 코드가 끝나고 모든 항목이 마지막 항목이 벡터에 "푸시 백"된 것과 같은지 여부입니다.

다른 개체가 벡터에서 대체되는 이유는 무엇입니까?

편집 :

class DEMData 
{ 
private: 
    int bitFldPos; 
    int bytFldPos; 
    const char* byteOrder; 
    const char* desS; 
    const char* engUnit; 
    const char* oTag; 
    const char* valType; 
    int index; 
public: 
    void SetIndex(int index); 
    int GetIndex() const; 
    void SetValType(const char* valType); 
    const char* GetValType() const; 
    void SetOTag(const char* oTag); 
    const char* GetOTag() const; 
    void SetEngUnit(const char* engUnit); 
    const char* GetEngUnit() const; 
    void SetDesS(const char* desS); 
    const char* GetDesS() const; 
    void SetByteOrder(const char* byteOrder); 
    const char* GetByteOrder() const; 
    void SetBytFldPos(int bytFldPos); 
    int GetBytFldPos() const; 
    void SetBitFldPos(int bitFldPos); 
    int GetBitFldPos() const; 
    friend std::ostream &operator<<(std::ostream &stream, DEMData d); 
}; 

편집 :

내가 XML 파일과 건물 DEMData 객체를 읽고있다 기반

DemData 클래스는 세터와 게터 간단한, 단지 데이터 구조입니다 각 xml 요소의 속성 :

DEMData demData; 
    for (i = 0; attr[i]; i += 2) 
    { 
     if(strcmp(attr[i],"BitFldPos") == 0) 
     { 
     demData.SetBitFldPos(*attr[i + 1] - '0'); 
     } 
     else if(strcmp(attr[i],"BytFldPos") == 0) 
     { 
     char* pEnd; 
     int tmp = strtol(attr[i + 1],&pEnd,10); 
     demData.SetBytFldPos(tmp); 
     } 
     else if(strcmp(attr[i],"ByteOrder") == 0) 
     { 
     demData.SetByteOrder(attr[i + 1]); 
     } 
     else if(strcmp(attr[i],"DesS") == 0) 
     { 
     demData.SetDesS(attr[i + 1]); 
     } 
     else if(strcmp(attr[i],"EngUnit") == 0) 
     { 
     demData.SetEngUnit(attr[i + 1]); 
     } 
     else if(strcmp(attr[i],"OTag") == 0) 
     { 
     demData.SetOTag(attr[i + 1]); 
     } 
     else if(strcmp(attr[i],"ValTyp") == 0) 
     { 
     demData.SetValType(attr[i + 1]); 
     } 
     else if(strcmp(attr[i],"idx") == 0) 
     { 
     char* pEnd; 
     int tmp = strtol(attr[i + 1],&pEnd,10); 
     demData.SetIndex(tmp); 
     } 
     //printf(" %s='%s'", attr[i], attr[i + 1]); 
    } 


    // Insert the data in the vector. 
    dems.push_back(demData); 
+3

더 많은 문맥을 사용할 수 있습니까? 예를 들어 함수에 있나요? 또한 동적 메모리 할당을 사용하는 이유는 무엇입니까? – GManNickG

+0

많은 코드가 없지만 여기에 메모리 누수가있을 수 있습니다. push_back은 객체의 복사본을 만듭니다. –

+0

동적 메모리 할당을 사용하지 않겠습니까? – Blade3

답변

6

왜 새로 할당 한 벡터입니까? 임시 DEMData 개체를 새로운 개체로 할당하는 이유는 무엇입니까?

당신이 DEMData을 삭제하지 않는 한하는 것은 새로운 할당 객체 있도록, 그것을하지 데이터 자체를 통과 무엇를 복사합니다 vector 저장

, 당신은 당신이에 항목을 밀어 메모리 이제까지 시간을 누출하고 벡터. 마찬가지로, 당신은 벡터를 동적으로 할당함으로써 메모리 누수 문제에 대해 스스로를 설정하고있다.

벡터의 모든 객체가 동일한 데이터를 포함하는 이유에 관해서는 동일한 사본이 더 많이 존재할 가능성이 매우 높습니다. 아마도 잘못된 사본 ctor와 결합 된 포인터를 사용하여 얕은 사본을 만듭니다. 하지 말아야 할 곳이 몇 군데 있지만 - 그 코드를 우리에게 보여주지 않았기 때문에 그것은 단지 추측 일뿐입니다.

편집 : 이제 DEMData 클래스의 코드를 추가 했으므로 포인터가 있고 사용자 정의 된 복사본이 없으므로 얕은 복사본이 생성됩니다 .

첫 번째 단계에서는 모든 포인터 char 멤버를 없애고 std::string으로 바꿉니다.int 회원은 괜찮을 것입니다. 값을 복사하면 복사됩니다.

Edit2가이 - std::string 변수 하나, 그리고 int 변수의 하나는 이러한 멤버 변수와 함께 무슨 일을하는지 감안할 때, 그것은 당신처럼 많은 두 std::map의 사용을 고려해야합니다 보인다.

+0

2Jerry : 새로운 방식으로 벡터를 할당하면 어떤 점에서 문제가됩니까? – Vlad

+1

아마도이 문제는 당면한 문제와 관련이 없지만, 원시 포인터를 매달 리는 것은 일반적으로 좋지 않습니다. 그것은 스택 할당되어야합니다. 그리고 실제로 동적으로 할당해야하는 경우에는이를 래핑해야합니다. – GManNickG

+0

2GMan : 실제로 코드에 몇 가지 다른 문제가 있습니다. 모두 찾아야합니까? IMHO는 처음에 실제 질문에 집중하는 것이 좋습니다. – Vlad

-2

이 경우 벡터 자체와 관련이 있습니다 ... (포인터를 스택에 할당하는 대신) 벡터에 대한 포인터와 demData을 사용하는 방식이 조금 의심 스럽습니다.

vector<DEMData>* dems = new vector<DEMData>(); 
DEMData demData 
// Build DEMDATA 

dems->push_back(demData); 
... 
delete dems; 

당신이 코드의 나머지 부분을 붙여 넣을 수 있습니다 : 나는 정상적인 C++ 코드는 다음과 같이하는 기대

? 또는 아마도 demData 구축을 수행하는 루프일까요?

+7

그때조차도 힙에'dems '를 가질 이유가 없습니다. 또한,'demData' 다음에 괄호를 제거하거나 함수를 선언하고 있습니다. – GManNickG

+0

@Orion Edwards :'DEMData demData()'는 객체 정의가 아닌 함수 선언입니다. – AnT

+0

woops. 오타가 수정되었습니다 –

3

벡터는 객체에 대한 참조가 아니며 사본입니다. 즉, 새로 생성 된 DEMData의 인스턴스를 벡터에 저장하고 객체를 업데이트하면 벡터 의 해당 항목이으로 업데이트되지 않습니다.

값이 아닌 포인터 DEMData*push_back을 포인터로 만들어야합니다.

0

DEMData 클래스에는 문자열의 메모리를 관리하기 위해 복사 생성자와 소멸자가 필요합니다. 그대로 (아마도) 일어나고있는 것은 DEMData 객체가 생성되어 동일한 포인터 값을 갖는 DEMData의 새 인스턴스를 만드는 벡터에 삽입된다는 것입니다. 그런 다음 원래의 DEMData을 소멸시킵니다 (소멸자가 없으므로). 벡터에서 포인터를 매달아 놓습니다. 그런 다음 새로운 DEMData을 만들면 우연히 같은 메모리 위치를 얻게되고 결국 모든 객체가 같은 위치를 가리 킵니다.

1

개체의 문자열이 같다고 가정합니다. 같은 demData 객체를 사용하여 벡터를 채우는 것 같습니다.

기본 복사 생성자를 사용하므로 모든 복사본에 동일한 (char *) 포인터가 포함됩니다. 이 포인터가 참조하는 메모리의 내용을 변경해야하는 경우 모든 복사본에 변경 내용이 표시됩니다.