1

在此示例中,我创建了一个包含一个整数的向量,然后从向量中删除该整数。向量的大小减小了,但整数仍然存在!为什么整数还在?大小为 0 的向量如何包含元素?

#include <vector>
#include <iostream>

using namespace std;

int main(int agrc, char* argv[])
{
    vector<int> v;
    v.push_back(450);

    cout << "Before" << endl;
    cout << "Size: " << v.size() << endl;
    cout << "First element: " << (*v.begin()) << endl;
    v.erase(v.begin());
    cout << "After" << endl;
    cout << "Size: " << v.size() << endl;
    cout << "First element: " << *(v.begin()) << endl;

    return(0);
}

输出:

Before
Size: 1
First element: 450
After
Size: 0
First element: 450
4

5 回答 5

10

您通过取消引用无效的内存位置来调用未定义的行为。通常,堆管理器不会立即释放delete出于效率目的而删除的内存。但是,这并不意味着您可以访问该内存位置,堆管理器可以随时将此内存位置用于其他目的。因此,如果您取消引用无效的内存位置,您的程序将出现不可预测的行为。

于 2011-03-23T06:37:09.353 回答
3

IIRC 除非特别告知,否则向量不会释放空间,因此您会看到仍在其内存中但未被向量跟踪的项目。这是您应该首先检查大小的部分原因(另一个是如果您从未分配过任何东西,您将取消引用垃圾指针)。

于 2011-03-23T06:38:53.653 回答
1

首先,不要指望它在所有系统中都是这种方式。向量如何在内部工作完全取决于实现。通过取消引用无效的内存位置,您可以规避文档中概述的行为。也就是说,您只能依靠 STL 文档中概述的行为工作。

您仍然可以访问该内存位置的原因是因为您正在使用的特定实现不会立即删除内存,而是将其保留一段时间(可能是出于性能目的)。如果作者愿意,另一种实现可以很好地立即删除该内存。

于 2011-03-23T06:44:35.170 回答
0

只是向量没有释放内存,而是保留它以备将来使用。

这就是我们所说的“未定义的行为” 无法保证下次它会起作用,并且它可能很容易在将来的尝试中使程序崩溃。不要这样做。

于 2011-03-23T06:41:12.667 回答
0

你的编译器选项是什么?我经常使用的两个编译器(g++ 和 VC++)在使用常用选项时都会崩溃。对于 g++,您必须为此行为设置一些附加选项(我认为是 -D_GLIBCXX_DEBUG);据我所知,它是 VC++ 的默认设置。(我对 VC++ 的命令只是“cl /EHs bounds.cc”。)

正如其他人所说,这是未定义的行为,但是使用好的编译器,它将被定义为导致程序崩溃。

于 2011-03-23T11:56:38.960 回答