gpt4 book ai didi

c++ - 试图读取充满对象的 vector 的访问冲突

转载 作者:行者123 更新时间:2023-11-30 03:52:31 25 4
gpt4 key购买 nike

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 类的对象保存在一个 vector 中。CJsonArray 没有复制构造函数,但有一个指针属性,所以我尝试自己制作一个(我第一次制作复制构造函数,我是 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 中实现一个 clone() 函数,它是一个抽象类和从它派生的类。以下是相关的代码片段:

cjson值.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(){};
};

cjson值.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.

调试信息:在第一个 push_back 上,第一个条目的成员已经损坏。在我实现 Copy-Constructor 之前程序已经在第二次或第三次推回时崩溃了,我猜是因为 vectore 必须重新分配他的条目并且找不到它们?难过的是,我第一次不得不处理这个问题。

所以我的问题是:我是否做错了复制构造函数?还是我完全走错了路,这与它无关?

我查看了许多其他处理类似问题的 Stackoverflow 问题,并尝试遵循那里的建议,但我想我在这个过程中做错了什么。

如果我需要提供其他信息,请告诉我。

预先感谢您的帮助!

最佳答案

CJsonValue::Clone() 方法需要是虚拟的。如果 CJsonArray 对象存储了 CJsonValue 对象的集合(与 CJsonValueNumber 或其他方式相反),则编译器无法知道 CJsonValueNumber 想要覆盖 Clone() 方法(如果它不是虚拟的)。

这会导致 CJsonValue::Clone() 总是被调用而不是 CJsonValueNumber::Clone()。此时您的数组中有 NULL 引用,这可能会导致您在 0x00000000 处发生访问冲突(NULL 定义为 0,或者0x00000000)。

因为 CJsonValue 无论如何都是一个抽象类(CJsonValue::ToString() 方法是虚空的),我会制作 CJsonValue::Clone() virtual void 也是。这将保证必须通过继承类来实现 Clone 方法。

总而言之,将 CJsonValue::Clone() 的声明更改为:

LIB_PRE virtual CJsonValue * Clone() = 0;

关于c++ - 试图读取充满对象的 vector 的访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30650017/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com