0

考虑以下代码:

#include <iostream>
#include <vector>

using namespace std;

class SomeClass {
public:
    SomeClass(int num) : val_(num) {}
    int val_;
    int val() const { return val_; }
};

// Given a vector of vector of numbers, this class will generate a vector of vector of pointers
// that point to SomeClass.
class Generator {
public:
    vector<SomeClass> objects_;
    vector<vector<SomeClass*> > Generate(const vector<vector<int> >& input) {
        vector<vector<SomeClass*> > out;
        for (const auto& vec : input) {
            out.push_back({});
            for (const int num : vec) {
                SomeClass s(num);
                objects_.push_back(s);
                out.back().push_back(&objects_.back());
            }
        }
        return out;
    }
};

int main() {
    Generator generator;
    auto output = generator.Generate({{2, 3}, {4, 5}, {6}});
    for (const auto& vec : output) {
        for (const auto* obj : vec) {
            printf("%d ",obj->val());
        }
        printf("\n");
    }
    return 0;
}

类中的Generate方法Generator将简单地将向量的向量ints 转换为指针向量的向量SomeClass

SomeClass只是一个int带有 getter 方法的简单值的容器。

我希望得到以下输出:

2 3
4 5
6

但是,我得到以下输出:

junk_integer junk_integer
4 5
6

第一行的指针似乎变成了悬空指针。这段代码有什么问题?

4

3 回答 3

1

如果调整大小导致向量容量发生变化,则所有增加 a 中元素数量的操作(std::vector包括)都会使所有引用向量元素的迭代器(包括指针)无效。push_back()

你的代码正在做

objects_.push_back(s);
out.back().push_back(&objects_.back());

在一个循环内。每次调用都会使 的objects_.push_back()迭代器无效objects_,因此可能导致out.back()包含无效(悬空)指针。

于 2017-07-31T12:03:35.510 回答
1

您将指针存储到 avector中,然后将元素添加到向量中。由于您没有为要添加的所有元素保留足够的空间,因此当向量调整大小时,它会使所有指向旧数据的指针无效。

您要么必须在存储指针之前保留足够的空间,要么在将所有内容存储在需要存储的向量中之后存储指针,或者不存储指针(也许存储索引)。

于 2017-03-26T04:41:56.433 回答
0

您正在存储指向中包含的对象的指针generator.objects_。当你调用它时,它们中的一些会变成悬空指针push_back()

通常,将指向对象的指针存储在 astd::vector中是一个坏主意。

于 2017-03-26T04:42:55.647 回答