I want to create a list of objects, by only saving a pointer to the very next object in each object.
#include <iostream>
class A
{
int v;
A *next;
public:
A(int temp):v(temp) {}
A* createNext()
{
A temp(v+1);
next = &temp;
return next;
}
int getv(){return v;}
};
int main()
{
A first(0);
A * next = first.createNext();
std::cout << next->getv() << "\n";
next = next->createNext();
std::cout << next->getv() << "\n";
}
When i execute this Programm, it gives me consistently a 1 for the first cout, but the second is a random number out of the range of an integer.
答案 0 :(得分:4)
在createNext()
函数中,您将在堆栈内存中创建一个对象,然后为其分配引用。但是,一旦该函数退出,堆栈帧将被清除,下一个指针将引用垃圾值。
A* createNext()
{
A temp(v+1); // this creates an object on the stack
next = &temp;
return next;
}
相反,您需要在堆上创建对象并返回它。堆内存不依赖于函数,可以在分配函数的范围之外访问。
A* createNext()
{
next = new A(v+1); // this creates an object on the heap
return next;
}
但是,如果在堆上分配对象(即使用new
),则需要在之后解除分配(即使用delete
)。如果不这样做会造成所谓的“内存泄漏”。
使用C ++的更多现代功能,可以减轻内存管理的一些缺陷。虽然考虑到你的问题的性质,你应该努力在使用这些抽象之前对C ++中的内存分配有一个充分的理解。
答案 1 :(得分:2)
使用
A temp(v+1);
next = &temp;
return next;
你创建一个“本地”变量,即一个具有自动存储持续时间的变量,其寿命在函数结束时结束,然后返回其地址。因此,您将返回超出范围的对象的地址,这是未定义的行为。
如果不仔细检查你的逻辑,只关注修复这个内存问题,你可能要编写
A* temp = new A(v+1);
next = temp;
return next;
答案 2 :(得分:0)
A* createNext()
{
A temp(v+1);
next = &temp;
return next;
}
您将返回指向本地对象temp
的指针,这将超出范围,指针将悬空。从那时起你所有的引用都是未定义的行为。考虑将std::unique_ptr
与共享结合使用。或者只使用提供的标准std::forward_list
。