vector 的增长函数是如何工作的?

How does vector's growth function work?

int main () {
    std::vector <int> elements;
    elements.push_back (1);
    elements [10000] = 102;
    std:: cout << elements [10000];
    return 0;
}

以上代码是如何工作的?据我所知,vector 的增长将是 1.5 - 2 倍。那么这里的第10000个元素是怎么存储的呢?这里的预期行为不是 "Segmentation fault" 吗?但是上面运行成功了。

So how is the 10000th element stored here?

元素 存储在向量中。它是 'stored' 在一段与向量无关的内存中。

Isn't the expected behavior here a "Segmentation fault"?

没有。行为未定义,因此没有预期的行为。

But the above runs successfully.

当行为未定义时,这是一种可能的行为。

您看到某些东西正在运行的事实并不意味着它是合法的,或者应该可以运行。 在这种情况下,如评论中所述,您确实越界阅读了。 在你的情况下,你很幸运(或者,实际上,不幸的是),并且对你来说一切都很好。 在其他情况下可能并非如此。例如,您可能会踩到别人的记忆。

你可以 运行 在 valgrind 下执行此操作,然后查看错误:

==31899== Invalid write of size 4 ==31899== at 0x400B30: main (in a.out) ==31899== Address 0x5a21c80 is 39,920 bytes inside an unallocated block of size 4,194,128 in arena "client" ==31899== ==31899== Invalid read of size 4 ==31899== at 0x400B47: main (in a.out) ==31899== Address 0x5a21c80 is 39,920 bytes inside an unallocated block of size 4,194,128 in arena "clien

t" ==31899==

您也可以尝试使用 .at() 而不是 []。 在这种情况下,您将抛出 out_of_range 异常。

通常小的越界读取不会产生段错误,因为您将从已经分配给您的进程的内存中读取。

仅当您尝试从当前未分配给您的应用程序的地址读取或写入时才会发生段错误。越界写入通常会通过覆盖重要的控制信息导致未来的内存访问越界而更快地导致段错误。

C++ 本身(通常)不会对原始内存访问进行边界检查,段错误是由 OS 生成的,它对您的应用程序的内存结构一无所知。