2015-06-04 25 views
1

edit: I made some changes and updated the code in this post based on the comments of Kyle and Dieter, so I fixed my Clone()function and added a assignment-operator to fulfil the rule of three. While this fixes were for sure badly needed, the same error prevails. Maybe my assignment operator is wrong?訪問衝突試圖讀取充滿對象的向量

我正在使用jsonplus庫我在線上找到了一個更大的項目。 我需要將類CJsonArray的對象保存在向量中。 CJsonArray沒有Copy-Constructor,但有一個指針屬性,所以我試圖自己做一個(第一次我做了一個複製構造函數,我是新來的C++)。

這裏是CJsonArray的相關部分:

cjsonarray.h

class CJsonArray : public CJsonValue 
    { 
    private: 
     std::vector <CJsonValue*> members; 
    public: 
     LIB_PRE CJsonArray(); 
     LIB_PRE CJsonArray(const CJsonArray * value); 
     LIB_PRE CJsonArray(const CJsonArray &); //the added copy constructor 
     LIB_PRE CJsonArray& operator=(const CJsonArray&); 
     LIB_PRE ~CJsonArray(); 

cjsonarray.cpp

CJsonArray::CJsonArray(const CJsonArray& ori) : members(ori.members.size()) { 
     for (std::size_t i = 0; i < ori.members.size()-1; ++i) 
      members[i] =ori.members[i]->Clone(); 
    } 
CJsonArray& CJsonArray::operator=(const CJsonArray& ori){ 
    for (std::size_t i = 0; i < ori.members.size() - 1; ++i){ 
     this->members[i] = ori.members[i]->Clone(); 
    } 
    return *this; 
} 

的方法,另外我不得不實施CJsonValue,克隆()函數是一個抽象類和從它派生的類。以下是相關的代碼段:

cjsonvalue.h

enum CJsonValueType 
{ 
    JV_STRING, 
    JV_NUMBER, 
    JV_OBJECT, 
    JV_ARRAY, 
    JV_NULL, 
    JV_BOOL 
}; 

class CJsonValue 
{ 
private: 
    CJsonValueType type; 
public: 
    LIB_PRE CJsonValue(); 
    LIB_PRE virtual ~CJsonValue(); 
    LIB_PRE CJsonValue(CJsonValueType type); 
    LIB_PRE virtual CJsonValue * Clone(); //the added Clone-Function 
    LIB_PRE virtual jstring ToString() const = 0; 
    LIB_PRE CJsonValueType GetType() const; 
    LIB_PRE virtual void Clear(){}; 
}; 

cjsonvalue.cpp派生類的

CJsonValue * CJsonValue::Clone(){ 
    return NULL; 
} 

例如,cjsonvaluenumber.h

class CJsonValueNumber : public CJsonValue 
{ 
private: 
    int value; 
public: 
    LIB_PRE CJsonValueNumber(int value); 
    LIB_PRE CJsonValueNumber(const CJsonValueNumber * value); 
    LIB_PRE CJsonValue * Clone(); 
    LIB_PRE jstring ToString() const; 
    LIB_PRE void GetValue(int & number) const; 
}; 

cjsonvaluenumber.cpp

CJsonValue * CJsonValueNumber::Clone(){ 
    return new CJsonValueNumber(*this); 
} 

main.cpp中產生的錯誤:

CJsonArray array1; 
CJsonArray array2; 
CJsonArray array3; 
CJsonArray array4; 
CJsonArray array5; 

array1.AddMember("test1"); 
array2.AddMember("test1"); 
array3.AddMember("test1"); 
array4.AddMember("test1"); 
array5.AddMember("test1"); 

arrays.push_back(array1); 
arrays.push_back(array2); 
arrays.push_back(array3); 
arrays.push_back(array4); 
arrays.push_back(array5); 

std::string str = arrays[0].ToString(); 

錯誤:

Unhandled exception at 0x026574BD in Message.exe: 0xC0000005: Access violation reading location 0x00000000.

debuginfo軟: 已經在第一的push_back的第一個條目的成員是腐敗。 在我實現Copy-Constructor之前,程序已經在第二個或第三個回退處崩潰了,我猜是因爲vectore不得不重新定位它的條目並且找不到它們?傷心的是,我第一次不得不面對這個問題。

所以我的問題是:我做的複製構造錯了嗎?還是我完全錯誤的方式,它與它無關?

我看了很多其他的Stackoverflow問題處理類似的問題,並試圖按照建議那裏,但我想我做了一些錯誤的方式。

如果我需要提供更多信息,請讓我知道。

在此先感謝您的幫助!

+1

大概:三第(5) - 缺少賦值運算符 –

+0

哇,謝謝你快回答!我會仔細看看的。同時,你能告訴我我是否在cjsonvalue.cpp中執行了clone()函數嗎?我很不確定在那裏返回NULL。 – Chenny

+0

你知道'Clone'不是*虛擬的,對嗎? – WhozCraig

回答

2

CJsonValue::Clone()方法需要是虛擬的。如果一個CJsonArray對象存儲了一組CJsonValue對象(而不是CJsonValueNumber或其他),則編譯器無法知道CJsonValueNumber想要覆蓋Clone()方法(如果它不是虛擬的)。

這將導致CJsonValue::Clone()總是被調用,而不是CJsonValueNumber::Clone()。此時,您的數組中有NULL引用,這可能會導致訪問衝突0x00000000NULL定義爲00x00000000)。

由於CJsonValue無論如何是一個抽象類(CJsonValue::ToString()方法是虛擬無效),我也會使CJsonValue::Clone()虛擬無效。這將保證克隆方法必須通過繼承類來實現。

總之,改變你的CJsonValue::Clone()聲明:

LIB_PRE virtual CJsonValue * Clone() = 0; 
+0

謝謝你,我改變了它,我相信這會是一個問題,以及,但我仍然得到同樣的錯誤執行的主要功能 – Chenny