gpt4 book ai didi

c++ - 将 std::vector 作为输入/输出引用参数传递时丢失了一些数据

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:54:43 26 4
gpt4 key购买 nike

我在函数之间传输 vector 中包含的某些数据时遇到问题。情况如下:

void generateObjects(std::vector<MyClass> &objects)
{
objects.clear();
//Fill objects vector
std::vector<MyClass> p;

//This 4-line pattern is repeated a number of times to generate all objects and store them in variable 'objects'
p.clear();
generateSomeOfTheObjects(p); //p is again passed by ref. in/out parameter
for(uint j = 0; j < p.size(); p++){
objects.push_back(p[j]);
}

//Print some members of the objects - works fine
for(uint i = 0; i < objects.size(); i++){
printf("%f ",objects[i].mymember->myElm);
}
}

int main()
{
std::vector<MyClass> objects;
generateObjects(objects);
//Print size of vector - size is correct it is the same as it is in generateObjects func
printf("%lu\n",objects.size());
//Again print members of the objects - some members are retained after the function call, some are lost.
//The one below doesn't work, mymember is a pointer to another object and its member myElm seems not initialized.
for(uint i = 0; i < objects.size(); i++){
printf("%f ",objects[i].mymember->myElm);
}
//Here I need to pass the objects to another read-only function
...
}

我在互联网上搜索了类似的案例,实际上发现了很多,但我无法对我的代码应用相同的修复。我正在尝试访问由 MyClass 实例成员 (objects[i].mymember->myElm) 指向的对象的成员,我可能在这里遗漏了什么?

最佳答案

可能错误在于MyClass的实现。我会说这个类包含一些用局部变量的地址初始化的指针,所以当你从一些函数返回时,指针指向一个被销毁的对象。

那将是未定义的行为,但它可能偶然起作用。当您从第一个函数返回时,堆栈内存最终被覆盖并且您的数据丢失。

更新:感谢@chris 在下面评论中的见解,最可能的原因是您的 MyClass 没有复制构造函数,但它确实有一个指针成员。

像这样:

class MyClass
{
public:
Member *mymember;

MyClass()
{
mymember = new Member;
}
~MyClass()
{
delete mymember;
}
};

现在,如果您使用编译器生成的默认复制构造函数(或复制运算符)会发生什么情况?

void foo()
{
MyClass a;
{
MyClass b(a);
}
//a.mymember is no longer valid
}

ab 共享同一个指针mymember,所以当其中一个被销毁时,mymember > 被删除,另一个持有悬空指针。

这就是为什么我们有三原则。它指出:

Whenever you define a non-default destructor, you most likely will want also a non-default copy-constructor and a non-default copy-operator.

现在您必须决定是要共享 mymember 的所有权还是要复制它。第一个最好用智能指针 (shared_ptr) 完成,第二个用深拷贝。

例如深拷贝:

class MyClass
{
public:
Member *mymember;

MyClass()
{
mymember = new Member;
}
MyClass(const MyClass &c)
{
mymember = new Member(c.mymember);
}
MyClass &operator=(const MyClass &c)
{
if (this != &c) //be aware of self-copy
{
delete mymember;
mymember = new Member(c.mymember);
}
return *this;
}
~MyClass()
{
delete mymember;
}
};

还有共享指针:

class MyClass
{
public:
std::shared_ptr<Member> mymember; //or boost::shared_ptr if old compiler

MyClass()
:mymember(new Member)
{
}
//no custom-made destructor -> no rule of 3
};

关于c++ - 将 std::vector 作为输入/输出引用参数传递时丢失了一些数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11621818/

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