指向向量中对象的指针有时指向向量中的不同对象

Posted

技术标签:

【中文标题】指向向量中对象的指针有时指向向量中的不同对象【英文标题】:Pointer to object in vector sometimes points to a different object in the vector 【发布时间】:2020-03-08 20:12:41 【问题描述】:

在下面的代码中,Struct2 中的 Struct1 指针应该始终指向 Struct1 的某个对象。这些结构中的每一个都包含在一个向量中。

但是,当我输出 Struct2 对象中指向的 Struct1 对象的索引变量时,在某些情况下会返回错误的变量。

为什么指向向量中包含的对象的指针有时会指向向量中的不同对象?

struct Struct1

    size_t index;
    std::vector<size_t> data;


struct Struct2

    Struct1 *s1;


class MyClass

    std::vector<Struct1> s1s;
    std::vector<Struct2> s2s;
    size_t propIndex = 0;

    void input(QByteArray &line)
    
        if (line == "1") 
            for (size_t i = s1s.size(); i <= propIndex; i++) 
                s1s.push_back( .index = i, .data=  );
            
            QByteArrayList list = getList();
            for (auto id : list)  s1s.at(propIndex).data.push_back(id.toULongLong());
        
        else 
            if (propIndex == s2s.size()) 
                s2s.push_back( .s1 = nullptr );
            

            if (line == "2") 
                size_t index = getIndex();
                for (size_t i = s1s.size(); i <= index; i++) 
                    s1s.push_back( .index = i, .data=  );
                
                s2s.at(propIndex).s1 = &s1s.at(index);
            
        

        propIndex++;
    

    QByteArrayList output()
    
        QByteArrayList output;

        for (auto s2 : s2s) 
            output += QByteArray::number(s2.s1->index) + "\n";
        

        return output;
    

【问题讨论】:

您好!请阅读Why is "Can someone help me" not an actual question。为了使这个问题可以回答,请详细说明您的代码的预期和实际行为。 @Brian 我试图重新表述这个问题:) 【参考方案1】:

问题是你把一个指针指向一个向量中的一个项目:

s2s.at(propIndex).s1 = &s1s.at(index);

vector 是一个动态结构,它的数据在增长时可能会重新分配。所以任何push_back() 都可以使所有指针失效:

s1s.push_back( .index = i, .data=  );

请注意,向量分配算法旨在为需要增长的几个元素保留空间。这解释了该问题仅不时出现。

一种解决方案可能不是保留指针,而是保留元素的索引以及指向向量的指针。

【讨论】:

谢谢,这就解释了。我认为您提出的解决方案会使我首先使用指针的原因无效,但无论如何我都必须找到不同的方法。 @xaxxon 是的,我正在考虑提出shared_ptr(因为根据设计,这些向量将在 s1s 和 s2s 之间共享)。但我认为 OP 首先需要这个向量来分配对象。 那么我能做的是独立分配对象并将unique_ptrs 放在向量中吗?如果是这样,一旦其unique_ptr 被释放/销毁,这些对象就会被销毁,对吧? @bur 是的,这确实是一个想法。但 unique_ptr 旨在保持唯一性。如果您的 s2s 是唯一使用它的人,您可以使用它。如果您需要相同指针的多个用户(例如在 s2s 和 s1s 中),请改为使用 shared_ptr。 @Christophe 仅在您想要共享所有权时使用共享ptr。否则,您需要一个唯一 ptr 向量和一个原始指针向量。在他的情况下,所有权生命周期是相同的,因此不需要共享 ptr 的额外开销。【参考方案2】:

正如 cmets 关于接受的答案所讨论的,一个可能的解决方案是使用 unique_ptrs。

在 OP 示例代码中,Struct1 向量将替换为 unique_ptr 向量:

    std::vector<std::unique_ptr<Struct1>> s1s;

然后需要独立分配对象并创建唯一指针存储在向量中,我们需要调用.get()来获取指向对象的原始指针:

    if (line == "1") 
        for (size_t i = s1s.size(); i <= propIndex; i++) 
            s1s.push_back(std::unique_ptr<Struct1>(new Struct1( .index = i, .data =  )));
        
        QByteArrayList list = getList();
        for (auto id : list)  s1s.at(propIndex)->data.push_back(id.toULongLong());
    

...

            if (line == "2") 
            size_t index = getIndex();
            for (size_t i = s1s.size(); i <= index; i++) 
                s1s.push_back(std::unique_ptr<Struct1>(new Struct1( .index = i, .data =  )));
            
            s2s.at(propIndex).s1 = s1s.at(index).get();

【讨论】:

以上是关于指向向量中对象的指针有时指向向量中的不同对象的主要内容,如果未能解决你的问题,请参考以下文章

如何计算指向不同向量数组中特定对象的指针的出现次数

我是不是正确删除了指向对象的指针向量?

检查指向向量 C++ 中对象的指针

何时使用向量中的对象以及何时使用指向向量中对象的指针? [关闭]

在删除指向动态分配对象的指针向量中的元素之前,我需要做啥?

当向量在内部类中时,如何删除指向对象的向量指针