1

这是一个创建Clustering对象并按值返回的方法。

Clustering ClusteringGenerator::makeOneClustering(Graph& G) {
    int64_t n = G.numberOfNodes();
    Clustering zeta(n);
    cluster one = zeta.addCluster();
    for (node v = G.firstNode(); v <= n; ++v) {
        zeta.addToCluster(one, v);
    }
    return zeta;
}

此循环多次调用该方法并将指向返回值的指针添加到向量中。

    int z = 3
    for (int i = 0; i < z; ++i) {
        // FIXME: why is zeta the same each iteration?
        Clustering zeta = clusterGen.makeOneClustering(G);
        DEBUG(&zeta);
        clusterings.push_back(&zeta);
    }

DEBUG 语句的输出是

0x7fff4ff894d0
0x7fff4ff894d0
0x7fff4ff894d0

所以这意味着&zeta在每次迭代中都是相同的指针。为什么?如何获得所需的结果(Clustering每次迭代创建一个对象并将其记住在向量中)?

4

4 回答 4

2

因为zeta是一个自动变量(循环中的那个,另一个也是局部变量,但本质上并没有错ClusteringGenerator::makeOneClustering),一旦当前循环迭代结束,它就不再存在(并且zeta' 的析构函数已经称为)。因此,编译器可以自由地将其底层存储重新用于更多变量(例如zeta来自下一个循环迭代的变量),并且不这样做是非常愚蠢的。

同样,您的代码也容易出错,因为它将局部变量的地址存储在容器中,尽管该变量在 之后不再存在,push_back如上所述。

为了解决这个问题,要么只使用 astd::vector<Clustering>并将这些东西按值放入,或者,如果你真的需要存储指针(可能是因为你不使用/从 C++11 的移动语义中获利,并且担心复制开销) ,然后动态分配这些循环对象,以防止它们被自动销毁。但是在后一种情况下(无论如何,您应该彻底过度考虑其用法,因为Clustering似乎可以很好地复制)您应该使用某种智能指针来处理动态分配的对象的正确销毁。

于 2013-01-08T15:15:26.833 回答
1

你可以定义

std::vector<Clustering> clusterings;

然后使用

clusterings.push_back(clusterGen.makeOneClustering(G));

如果您使用的是 c++11 并且集群是可移动的,您甚至不会生成副本。此解决方案更快,您不必处理原始指针。

于 2013-01-08T15:25:25.183 回答
0

那是因为你打印出你创建的变量的地址,而且它总是一样的。向量也是如此。您存储的是地址而不是实际值。如果要存储该值,请尝试使用它。

clustering.push_back(zeta);

现在您存储的是值而不是地址....

于 2013-01-08T15:22:28.697 回答
-1
Clustering * ClusteringGenerator::makeOneClustering(Graph& G) {
    int64_t n = G.numberOfNodes();
    Clustering * zeta = new Clustering(n);
    cluster one = zeta.addCluster();
    for (node v = G.firstNode(); v <= n; ++v) {
        zeta.addToCluster(one, v);
    }
    return zeta;
}

此循环多次调用该方法并将指向返回值的指针添加到向量中。

int z = 3
for (int i = 0; i < z; ++i) {
    // FIXME: why is zeta the same each iteration?
    Clustering * zeta = clusterGen.makeOneClustering(G);
    DEBUG(zeta);
    clusterings.push_back(zeta);
}
于 2013-01-08T15:21:06.563 回答