Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当向量需要更多内存并重新分配内存时,指针会发生什么情况?_C++_Pointers_Vector_Memory Management - Fatal编程技术网

C++ 当向量需要更多内存并重新分配内存时,指针会发生什么情况?

C++ 当向量需要更多内存并重新分配内存时,指针会发生什么情况?,c++,pointers,vector,memory-management,C++,Pointers,Vector,Memory Management,当vector需要更多内存时,它会在某个地方重新分配内存,我还不知道在哪里!然后指针就失效了,有什么好的解释吗 我是说他们去了哪里,我的集装箱怎么了?(不是链表类)当您使用std::vector时,该类负责有关内存分配、指针、大小调整等的所有细节 vector类通过迭代器和引用公开其内容。向量的突变可能会使迭代器和引用无效,因为可能需要重新分配 使用指针访问内容是有效的,因为vector类保证将其元素存储在连续的内存位置。显然,由于可能的重新分配,列表的任何变异都可能使指向其内容的任何指针失效。

当vector需要更多内存时,它会在某个地方重新分配内存,我还不知道在哪里!然后指针就失效了,有什么好的解释吗


我是说他们去了哪里,我的集装箱怎么了?(不是链表类)

当您使用
std::vector
时,该类负责有关内存分配、指针、大小调整等的所有细节

vector
类通过迭代器和引用公开其内容。向量的突变可能会使迭代器和引用无效,因为可能需要重新分配

使用指针访问内容是有效的,因为
vector
类保证将其元素存储在连续的内存位置。显然,由于可能的重新分配,列表的任何变异都可能使指向其内容的任何指针失效。因此,如果您曾经使用指针访问元素,那么一旦您改变了向量,您必须将这些指针视为无效。简言之,指向内容的指针和引用的指针适用相同的规则


如果您希望维护对向量中某个项的引用,并使该引用在变异后仍然有效,那么您应该记住索引,而不是对该项的指针或引用。在这种情况下,添加到向量的末尾是完全安全的,并且您的索引值仍然引用相同的元素。

简短回答:一切都会很好。别担心,回去工作吧

中等回答:向向量添加元素或从向量中删除元素会使所有迭代器和引用/指针无效(可能从后面删除的情况除外)。就这么简单。在这样的操作之后,不要引用任何旧的迭代器并获取新的迭代器。例如:

std::vector<int> v = get_vector();

int & a = v[6];
int * b = &v[7];
std::vector<int>::iterator c = v.begin();
std::advance(it, 8);

v.resize(100);
std::vector v=get_vector();
int&a=v[6];
int*b=&v[7];
std::vector::迭代器c=v.begin();
std::advance(it,8);
v、 调整大小(100);
现在
a
b
c
都是无效的:您不能使用
a
,也不能取消对
b
c
的引用


详细回答:向量跟踪动态内存。当内存耗尽时,它会在别处分配一个新的、更大的块,并复制(或移动)所有旧元素(然后释放旧内存,销毁旧对象)。内存分配和解除分配由分配器(通常为
std::allocator
)完成,分配器通常依次调用
::operator new()
)来获取内存,后者通常依次调用
malloc()
。详细信息可能因平台而异。在任何情况下,任何以前持有的引用、指针或迭代器都不再有效(可能是因为它们引用了现在释放的内存,尽管标准中没有指定它们无效的原因)。

当您从
向量添加或删除项时,指向其中项的所有迭代器(和指针)都将无效。如果需要在向量中存储指向某个项的指针,请将该向量设置为常量,或使用其他容器


向量在哪里存储东西对你来说应该无关紧要。你不需要做任何事情,只需要让它完成它的工作。

一些代码来证明这一点是有用的……我认为这可能是一个问题:
std::vector foo(10);int*ip=&foo.front()。重新分配可能会使ip无效,对吗?但是,您不应该这样滥用std::vector。使用迭代器。Protip:使用索引而不是指针。@zerm重新分配也会使迭代器无效。顺便说一句,它不会使
*ip
无效,当然,只有
ip
@ChristianRau是的,对不起,您在这两方面都完全正确。您可以使用&vect[0]访问内部指针。。。不建议使用,但很有可能。我有时使用
&vect.front()
:例如,将OpenGL顶点存储在
std::vector
中并使用它。然而,最终一些OpenGL函数需要一个
浮点*
,所以只需传递
&vect.front()
@David我的观点是,尽管这个答案声称,您确实有访问权。@WillBickford只有在您滥用引用的情况下。@David大多数情况下,您必须知道的唯一一件事是数据是连续存储的(即使你不一定要知道),这也是你一直都知道的事实(假设你知道你在标准C++中工作)。当标准保证了它的行为时,我绝对不会称之为滥用。指向引用的指针有什么坏处,这根本不是滥用。但是……你是什么意思“一切都会好起来的”?我以为OP考虑使用指针,指向矢量数据?我认为只有他放弃这个想法,一切都会好起来。我不认为你回答了实际的问题,这是关于指向矢量数据的指针,在重新分配之前获得的。好吧,我仍然同意下行投票人(我假设MacMake是)你应该提到指针会发生什么。或者至少用这样的措辞提问,我宁愿避免说一切都会好起来。我的意思是,简短的回答是唯一引起关注的部分。我仍然觉得“一切都会好起来”有点误导。:X我认为在我有指向向量元素的指针,“那很好”不太好。从C的角度来看,看看这个:当然,它不会工作,而且这样编码是危险的。但我认为OP对向量的使用感到困惑,实际上是在问这样的代码在使用向量时是否可以。。。