我有以下课程:
class A {};
class B { vector<A> vect; };
我可以像这样访问任意A:
A a = b.vect[0];
// A *a_ptr = &a;
但我怎样才能直接进入* a_ptr?
A *a_ptr = &b.vet[0];
编译并且不会给出运行时错误,但它指向错误的内存位置。
修改
我的真实世界示例:http://ideone.com/kP8NK
当Ideone提供预期的“You are now at 0, 0, 0
”时,MS VisualStudio编译器会产生“You are now at 6624656, -33686019, -1414812757
”
答案 0 :(得分:6)
这不是“错误”,你只是错过了差异。即:
A a = b.vect[0]; // Makes `a` a *copy* of the vector element
A *a_ptr = &a; // Address of the copy
A *a_ptr2 = &b.vect[0]; // Address of the element, not a copy
要获得等效性,您应该将第一个更改为:
A& a = b.vect[0]; // Makes `a` a reference to the vector element
A *a_ptr = &a; // Address of the element, not a copy
如果您在观察到这种差异后仍未达到预期效果,那么您需要向我们展示您的确切示例,以及您如何确定“正确”和“错误”结果。
问题是std::vector<>::push_back
会在size() == capacity()
时使元素的引用,指针和迭代器无效,因为它需要分配一块新的内存。使用无效指针(等)会导致未定义的行为,因此您的结果是未知的。
您应该存储索引,并进行简单的查找以获取实际元素。 (注意vector
仍然是有序的,所以即使你的房间可能在内存中移动,它们的索引也是一样的。)
答案 1 :(得分:2)
A *a_ptr = &b.vect[0];
是正确的。如果它对您不起作用,那么您正在做其他事情,或者在获取指针后修改向量。向量修改通常使其元素上的所有指针和迭代器无效。
答案 2 :(得分:1)
它适用于我(将vet
更改为vect
后)。有关证据,请参阅http://ideone.com/V3tGS。
答案 3 :(得分:1)
你的问题是你把地址带到指针后修改了矢量。这里:
World w;
w.worldMap.push_back(Room(0, 0, 0)); // starting point
Room *starting_room = &w.worldMap[0];
w.worldMap.push_back(Room(1, 1, 5)); // treasure room
Room treasure_room = w.worldMap[1];
修改容器会使所有指针/引用无效。
如果删除这些行:
w.worldMap.push_back(Room(1, 1, 5)); // treasure room
Room treasure_room = w.worldMap[1];
完美无缺