我无法在我的函数之间传输向量中包含的一些数据。情况如下:
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-&gt; myElm)我可能在这里失踪了什么?
答案 0 :(得分:2)
错误可能在于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
};
答案 1 :(得分:0)
也许与你的问题无关,但是这个:
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所提到的,你复制的问题是,你没有使用你的拷贝构造函数进行深层复制。