将std::vector作为输入/输出引用参数传递时丢失了一些数据
Some data lost while passing std::vector as in/out reference parameter
我在函数之间传输矢量中包含的一些数据时遇到问题。情况如下:
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("%lun",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
}
a
和b
共享相同的指针mymember
,因此当其中一个被破坏时,mymember
被删除,而另一个持有悬挂指针。
这就是为什么我们有三规则。它指出:
无论何时定义非默认析构函数,都很可能需要一个非默认复制构造函数和一个非缺省复制运算符。
现在,您必须决定是要共享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
};
也许与您的问题无关,但这是:
void generateObjects(std::vector<MyClass> &objects)
{
objects.clear();
std::vector<MyClass> p;
p.clear();
generateSomeOfTheObjects(p);
for(uint j = 0; j < p.size(); p++){
objects.push_back(p[j]);
}
for(uint i = 0; i < objects.size(); i++){
printf("%f ",objects[i].mymember->myElm);
}
}
与此相同:
void generateObjects(std::vector<MyClass> &objects)
{
objects.clear();
generateSomeOfTheObjects(objects);
std::reverse(objects.begin(), objects.end());
for(uint i = 0; i < objects.size(); i++) {
printf("%f ",objects[i].mymember->myElm);
}
}
正如@rodrigo所提到的,复制问题是您没有使用复制构造函数进行深度复制。
相关文章:
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用指向成员的指针将成员函数作为参数传递
- 如何将参数传递给正在使用模板的类
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 修改函数中的指针(将另一个指针作为参数传递)
- 如何将部分流作为参数传递
- 我正在开发服务器,ip作为参数传递不起作用
- 将私有数据成员作为默认参数传递给该类的公共方法时出错
- 如何将从第 2 个字符开始的字符串作为函数中的参数传递以进行递归,并约束数据 tiee 是函数中的字符串?
- 将非静态数据成员作为默认参数传递给方法
- 即使数据类型不同,是否有可能将帧的参数作为参数传递给回溯中的另一个帧
- 将任何数据类型/对象作为参数传递以确定其大小
- 如何在不将类数据成员作为参数传递的情况下访问线程中的类数据成员
- 将std::vector作为输入/输出引用参数传递时丢失了一些数据
- 如何在 c++ 中将数据文件作为参数传递到函数中
- 将指向数据的指针作为参数传递给期望二维数组的函数
- 授予静态函数对数据的访问权限,而不将数据作为参数传递
- 从函数中作为参数传递的对象访问矢量数据
- 这段代码是否在作为参数传递时处理数据有点困惑
- 未能将指向常量数据的指针作为函数模板参数传递