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 ++指针对象与非指针对象[重复]

为啥C ++允许将指向基对象的指针转换为派生类的指针[重复]

c ++ * vs&在函数声明中[重复]

将指针向量传递给c ++中的函数[重复]

指向从未被设为 const 的 const 对象的 C++ 指针 [重复]

没有 new 关键字并使用指针的 C++ 对象初始化 [重复]