C++ STL 容器和指针有效性

发布于 2024-10-06 06:18:05 字数 724 浏览 0 评论 0原文

考虑这段代码:

Uint counter = 0;

int* p1;
int* p2;

deque<int>  dequeInstance;
vector<int> vectorInstance;

dequeInstance.push_back(3);
dequeInstance.push_back(7);

p1 = &dequeInstance.back();

dequeInstance.push_back(17);

p2 = &dequeInstance.back();

if(*p1 == !7)
    ++counter;

if(*p2 == !17)
    ++counter;

vectorInstance.push_back(3);
vectorInstance.push_back(7);

p1 = &vectorInstance.back();

vectorInstance.push_back(17);

p2 = &vectorInstance.back();

if(*p1 == !7)
    ++counter;

if(*p2 == !17)
    ++counter;



return counter;

我本来期望当我将第三个元素推到向量的后面时,指向第二个元素的指针将无效,因为我对 std::vector 的理解是它是一个直数组每次修改时都会被擦除并重新创建。然而,到此代码结束时,“计数器”等于零。

我在这里缺少什么?

Consider this piece of code:

Uint counter = 0;

int* p1;
int* p2;

deque<int>  dequeInstance;
vector<int> vectorInstance;

dequeInstance.push_back(3);
dequeInstance.push_back(7);

p1 = &dequeInstance.back();

dequeInstance.push_back(17);

p2 = &dequeInstance.back();

if(*p1 == !7)
    ++counter;

if(*p2 == !17)
    ++counter;

vectorInstance.push_back(3);
vectorInstance.push_back(7);

p1 = &vectorInstance.back();

vectorInstance.push_back(17);

p2 = &vectorInstance.back();

if(*p1 == !7)
    ++counter;

if(*p2 == !17)
    ++counter;



return counter;

I would have expected that when I pushed the third element to the back of the vector, the pointer to the second element would have been invalidated, as my understanding of std::vector is that its a straight array which is wiped and recreated every time its modified. By the end of this code however 'counter' is equal to zero.

What am I missing here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

前事休说 2024-10-13 06:18:05

希望出于性能考虑,std::vector 不会“每次修改时都会被擦除并重新创建”。

向量的容量可能会超过其大小,这意味着它可以分配比实际使用更多的内存。当您push_back时,仅当新大小大于旧容量时才会发生重新分配,并且在这种情况下,迭代器将失效。

在您的情况下,您应该在 std::vector 实例化之后立即检查 capacity 的值。您将看到它毫无疑问大于 3,因此,您的任何 push_back 调用都不会触发重新分配,并且所有迭代器仍然有效。

另请注意,std::vector 提供了一个 reserve 成员函数,允许您控制向量容量。当您知道需要插入多少元素以避免不可告人的重新分配时,这非常有用。

Hopefully for performance, std::vector is not 'wiped and recreated every time it's modified'.

A vector has a capacity which may exceed its size, which means that it can allocate more memory than truly used. When you push_back, a reallocation will only occur if the new size is greater than the old capacity, and in this case, iterators are invalidated.

In your case, you should check the value of capacity right after the std::vector instantiation. You will see that it's without any doubt greater than 3, thus, none of your push_back calls trigger a reallocation and all iterators remain valid.

Also note that std::vector provides a reserve member function which allow you to control the vector capacity. This is really useful when you know how many elements are expected to be inserted in order to avoid ulterior reallocation.

深居我梦 2024-10-13 06:18:05

好吧,你有一些问题。首先,!n = 0,除非n = 0,然后它等于1。因此计数器永远不会增加。

其次,当您push_back一个新元素时,向量不一定会破坏内容。向量有 2 个“大小”。 1 是向量中的元素数量,2 是分配的内存量。仅当分配的内存量用完时,向量才会被重新分配和复制。

此外,删除内存区域后,内存不一定会被清除,并且可能仍然指向有效数据。

您没有使用迭代器,因此它们不会失效。您正在使用指针,它们只是指向内存区域。仅仅因为未分配内存并不意味着指针无效。这是 C/C++ 给您带来的主要危险之一。确保你不要做这样的事情,因为你正在调用“未定义的行为”,它可以做任何事情,从“不会引起任何问题并且看似工作”到“可怕地崩溃并以危险的方式关闭你的操作系统”。

Ok you have a few problems. Firstly, !n = 0 unless n = 0 and then it equals 1. Therefore counter never gets incremented.

Secondly a vector does not necessarily destroy the contents when you push_back a new element. A vector has 2 "sizes". 1 is the number of elements in the vector and 2 is the amount of memory allocated. The vector only gets reallocated and copied when the amount of memory allocated runs out.

Furthermore after you have deleted an area of memory the memory is not necessarily cleared and may still point at valid data.

You aren't using iterators so they don't get invalidated. You are using pointers and they are simply pointing at an area of memory. Just because that memory isn't allocated does not mean that the pointer is invalid. This is one of the major dangers that C/C++ can leave you with. Make sure you don't do things like this as you are invoking "undefined behaviour" which can do anything from "not cause any problems and seemingly work" through to "crash horrifically and bring down your operating system in a dangerous way".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文