下面是一个创建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);
}调试语句的输出为
0x7fff4ff894d0
0x7fff4ff894d0
0x7fff4ff894d0所以这意味着&zeta在每次迭代中都是相同的指针。为什么?我怎样才能得到想要的结果(每次迭代创建一个Clustering对象并在向量中记住它)?
发布于 2013-01-08 23:15:27
因为zeta是一个自动变量(循环中的那个,好吧,另一个也是局部变量,但ClusteringGenerator::makeOneClustering本身没有什么问题),一旦当前循环迭代结束(并且调用了zeta的析构函数),它就不再存在了。因此,编译器可以自由地重用它的底层存储来存储更多的变量(比如下一次循环迭代中的zeta ),而不这样做将是非常愚蠢的。
同样,您的代码也容易出错,因为它将局部变量的地址存储在容器中,尽管该变量在push_back之后不再存在,如上所述。
要解决这个问题,要么使用std::vector<Clustering>并按值将这些内容放入,要么如果你真的需要存储指针(可能是因为你不使用C++11的移动语义并担心复制开销),那么动态分配这些循环对象,以防止它们被自动销毁。但在后一种情况下(考虑到Clustering似乎具有很好的可复制性,您无论如何都应该仔细考虑它的用法),您应该使用某种智能指针来关注动态分配对象的正确销毁。
发布于 2013-01-08 23:25:25
你可以定义
std::vector<Clustering> clusterings;然后使用
clusterings.push_back(clusterGen.makeOneClustering(G));如果您使用的是c++11,并且集群是可移动的,那么您甚至不需要生成副本。这种解决方案速度更快,而且您不必处理原始指针。
发布于 2013-01-08 23:22:29
这是因为您打印出的是您创建的变量的地址,而它始终是相同的。向量也是如此。您存储的是地址,而不是实际值。如果您想存储值,请尝试使用此命令。
clustering.push_back(zeta);现在您存储的是值,而不是地址...
https://stackoverflow.com/questions/14218005
复制相似问题