我遇到了一个我不太明白的问题:
我正在使用
创建一个对象Edgeedge_vec1.push_back(Edge(src,dest));
然后我想在一个单独的向量中保留指向此Edge的指针:
edge_vec2.push_back(&edge_vec1.back());
但是,一旦我添加了第二个Edge对象,指向edge_vec2中第一个Edge的指针就会失效(获取一些随机数据)。是因为edge_vec2中的指针实际指向edge_vec1中的某个位置,而不是底层元素?我可以通过在堆上创建我的Edge对象来避免这种情况,但我想了解发生了什么。
谢谢。
答案 0 :(得分:3)
当向元素添加新元素时,可以重新分配向量。因此,指向向量元素的指针的先前值可能无效。
您应该首先为矢量保留足够的内存以防止重新分配。
➜ ~ jhipster --help
Usage: jhipster [command] [options]
Commands:
app Create a new JHipster application based on the selected options
aws Deploy the current application to Amazon Web Services
ci-cd Create pipeline scripts for popular Continuous Integration/Continuous Deployment tools
client Create a new JHipster client-side application based on the selected options
cloudfoundry Generate a `deploy/cloudfoundry` folder with a specific manifest.yml to deploy to Cloud Foundry
docker-compose Create all required Docker deployment configuration for the selected applications
entity [name] Create a new JHipster entity: JPA entity, Spring server-side components and Angular client-side components
export-jdl [jdlFile] Create a JDL file from the existing entities
heroku Deploy the current application to Heroku
import-jdl [jdlFiles...] Create entities from the JDL file passed in argument
info Display information about your current project and system
kubernetes Deploy the current application to Kubernetes
languages [languages...] Select languages from a list of available languages. The i18n files will be copied to the / webapp/i18n folder
openshift Deploy the current application to OpenShift
rancher-compose Deploy the current application to Rancher
server Create a new JHipster server-side application
service [name] Create a new Spring service bean
upgrade Upgrade the JHipster version, and upgrade the generated application
completion Print command completion script
Options:
-h, --help output usage information
-d, --debug enable debugger
-V, --version output the version number
For more info visit https://jhipster.github.io
➜ ~
答案 1 :(得分:3)
来自http://en.cppreference.com/w/cpp/container/vector/push_back:
如果new size()大于capacity(),则所有迭代器和引用(包括last-the-end迭代器)都将失效。否则只有过去的迭代器无效。
当您向其添加项目时,依赖于vector
中对象的指针/引用是一个坏主意。最好存储索引的值,然后使用索引从vector
中获取项目。
edge_vec2.push_back(edge_vec1.size()-1);
稍后,您可以使用:
edge_vec1[edge_vec2[i]]
表示某些有效值i
。
答案 2 :(得分:1)
std :: vector的要求是底层存储是一个连续的内存块。因此,当您要插入元素但当前分配的块不足以容纳其他元素时,向量必须重新分配其所有元素。发生这种情况时,所有迭代器和指针都会失效,因为完整的块被重新分配(移动)到完全不同的内存部分。
成员函数容量可用于查询可插入的最大元素数量,而无需重新分配底层内存块。查询此示例代码:
std::vector<int> vec;
for(int i = 0; i < 1000; i++) {
bool still_has_space = vec.capacity() > vec.size();
if (!still_has_space) std::cout << "Reallocating block\n";
vec.push_back(i);
}
如果不需要连续内存布局的强保证,最好使用std :: deque而不是std :: vector。它允许在任一端推动元件而不移动任何其他元素。您可以通过稍微更差的迭代速度进行交易。
std::deque<int> deq;
std::vector<int*> pointers;
for(int i = 0; i < 1000; i++) {
deq.push_back(i);
pointers.push_back(&deq.back());
}
for(auto p : pointers) std::cout << *p << "\n"; // Valid