c ++指针对象列表[重复]
Posted
技术标签:
【中文标题】c ++指针对象列表[重复]【英文标题】:c++ object list by pointer [duplicate] 【发布时间】:2018-01-23 19:42:03 【问题描述】:我想创建一个对象列表,只在每个对象中保存一个指向下一个对象的指针。
#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";
当我执行这个程序时,它总是给我一个 1 作为第一个 cout,但第二个是一个整数范围之外的随机数。
【问题讨论】:
你考虑过std::forward_list
吗?另外,不要存储函数局部变量的地址,即UB
您正在堆栈中创建一个临时 A 实例,并将其地址存储在下一个成员变量中。一旦你退出 createNext 函数,那个地址就会变成垃圾
为什么投反对票?这是一个完整的代码示例,清楚地解释了想要什么以及出了什么问题。仅仅因为答案是显而易见且众所周知的,这并不意味着它是一个坏问题
【参考方案1】:
在您的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++ 中的内存分配有一个扎实的理解。
【讨论】:
我认为您可能想要将列表包装在拥有的外部句柄中或使用std::shared_ptr
。当然还有其他方法【参考方案2】:
有
A temp(v+1);
next = &temp;
return next;
您创建一个“本地”变量,即具有自动存储期限的变量,其生命周期在函数结束时结束,然后返回其地址。因此,您将返回超出范围的对象的地址,这是未定义的行为。
没有过多地检查你的逻辑,只专注于解决这个内存问题,你可能不得不写
A* temp = new A(v+1);
next = temp;
return next;
【讨论】:
【参考方案3】: A* createNext()
A temp(v+1);
next = &temp;
return next;
您正在返回一个指向本地对象temp
的指针,这将超出范围并且指针将悬空。从那时起,您的所有取消引用都是未定义的行为。考虑将std::unique_ptr
与shared 结合使用。或者只使用std::forward_list
提供的标准。
【讨论】:
您的文字表明 unique_ptr 将解决本地超出范围的问题。它不会。我不认为你的意思是,但这就是它的阅读方式 @pm100 而不是会员。以上是关于c ++指针对象列表[重复]的主要内容,如果未能解决你的问题,请参考以下文章
为啥C ++允许将指向基对象的指针转换为派生类的指针[重复]