【发布时间】:2020-02-17 01:30:53
【问题描述】:
我有一个对象,我试图复制任意多次,并对该对象进行了一些细微的更改。我想将指向那些重复对象的指针存储在std::vector 中。我正在使用for 循环来尝试实现结果。但是,我注意到std::vector<T *> 在循环退出后指向相同的地址。我尝试用std::string 复制对象,我看到了相同的效果。这是我的代码 sn-p。
int main() {
auto name = new std::string("fido");
const int size = 3;
std::vector<std::string *> names;
names.reserve(size);
for (int i = 0; i < size; i++) {
std::string n = *name + " " + std::to_string(i);
names.push_back(&n);
}
// nothing from this loop prints out
for (auto n : names) {
std::cout << *n << std::endl;
}
return 0;
}
当我将代码放入调试器时,我看到names 将指针全部存储到相同的内存地址:0x7ffffffeead0。关于我在这里做错了什么有什么想法吗?
我修改了代码来存储一个字符串向量,然后循环遍历每个字符串,创建一个指向每个字符串地址的指针,如下所示。这种方法也行不通。指针向量仍然指向同一个地址;虽然这一次,它们都指向最后一个字符串的地址。
int main() {
auto name = new std::string("fido");
const int size = 3;
std::vector<std::string *> pointers;
std::vector<std::string> names;
names.reserve(size);
pointers.reserve(size);
for (int i = 0; i < size; i++) {
std::string n = *name + " " + std::to_string(i);
names.push_back(n);
}
for (int i = 0; i < size; i++) {
auto n = names.at(i);
auto p = &n;
pointers.push_back(p);
}
for (auto n : names) {
std::cout << n << std::endl;
}
for (auto n : pointers) {
std::cout << *n << std::endl;
}
return 0;
}
然而,在第三次尝试中,我将代码修改如下。请注意,我使用& 运算符来按索引访问元素。在这里,我确实得到了一个指向不同地址的std::vector<std::string *>(正确对应于字符串向量)。
int main() {
auto name = new std::string("fido");
const int size = 3;
std::vector<std::string *> pointers;
std::vector<std::string> names;
names.reserve(size);
pointers.reserve(size);
for (int i = 0; i < size; i++) {
std::string n = *name + " " + std::to_string(i);
names.push_back(n);
}
for (int i = 0; i < size; i++) {
auto p = &names.at(i); // using address operator like this "works"
pointers.push_back(p);
}
for (auto n : names) {
std::cout << n << std::endl;
}
for (auto n : pointers) {
std::cout << *n << std::endl;
}
return 0;
}
最后,我终于得到了这个更简洁的例子。在这里,我在每个循环上创建一个新指针。
int main() {
auto name = new std::string("fido");
const int size = 3;
std::vector<std::string *> names;
names.reserve(size);
for (int i = 0; i < size; i++) {
auto x = new std::string(*name + " " + std::to_string(i));
names.push_back(x);
}
for (auto n : names) {
std::cout << *n << std::endl;
}
return 0;
}
for-loops 上是否有一些我在这里遗漏的指针?任何指向 C++ 范围规则的指针(不是双关语)都将不胜感激。
【问题讨论】:
标签: c++ for-loop pointers c++17