"矢量下标超出范围"使用std :: vector作为std :: map

时间:2017-01-12 07:55:16

标签: c++ c++11 vector

我有以下代码,这是我尝试做的简化版本。

std::vector<GLuint> testVector = { 6, 7, 8 };
std::map<std::pair<GLfloat, GLfloat>, std::vector<GLuint>> testMap;
testMap.insert(std::make_pair(std::make_pair(1.0f,1.0f), testVector));

std::vector <GLuint> retrievalVector =
                                  testMap.find(std::make_pair(1.0f, 1.0f))->second;

std::cout << "Retrieval Vector: " << retrievalVector[0] << "\t" 
                                  << retrievalVector[1] << "\t" 
                                  << retrievalVector[2] << std::endl;

retrievalVector.push_back(9);

std::cout << "Retrieval Vector: " << retrievalVector[0] << "\t" 
                                  << retrievalVector[1] << "\t" 
                                  << retrievalVector[2] << "\t" 
                                  << retrievalVector[3] << std::endl;

testMap.insert(std::make_pair(std::make_pair(1.0f, 1.0f), retrievalVector));
retrievalVector = testMap.find(std::make_pair(1.0f, 1.0f))->second;

std::cout << "Retrieval Vector: " << retrievalVector[0] << "\t" 
                                  << retrievalVector[1] << "\t" 
                                  << retrievalVector[2] << "\t" 
                                  << retrievalVector[3] << std::endl;

基本上,我使用坐标作为关键字将一个整数向量插入到地图中。我检索相同的向量,发现内容已成功存储。然后我向向量添加另一个整数并将其重新插入到相同的位置。再次检索它并尝试打印矢量的内容(最后一个cout)会导致超出范围访问。

知识渊博的人可以解释为什么会这样吗?

2 个答案:

答案 0 :(得分:1)

行为完全符合预期。 According to the documentation

  

如果容器尚未包含具有等效键的元素,则将元素插入容器中。

您已经有std::make_pair(1.0f, 1.0f),因此您的返回值应为:

  

返回一个由插入元素的迭代器(或阻止插入的元素)组成的对,以及表示插入是否发生的bool。

如果你检查testMap.insert(std::make_pair(std::make_pair(1.0f, 1.0f), retrievalVector)).second它应该是false,那么那里仍然有一个三元素数组,而不是你希望添加的四元素数组,因此程序在尝试时崩溃访问retrievalVector[3]

顺便说一下,C ++ 17有一个insert_or_assign()函数可以完成你希望insert()做的事情。

答案 1 :(得分:1)

问题是你的第二个insert失败,因为你已经在那个位置有一个值。如果要修改该值,则必须执行testMap[std::make_pair(1.0f, 1.0f)] = retrievalVector;

之类的操作