【问题标题】:How does vector's growth function work? [closed]向量的增长函数是如何工作的? [关闭]
【发布时间】:2018-09-13 19:34:25
【问题描述】:
int main () {
    std::vector <int> elements;
    elements.push_back (1);
    elements [10000] = 102;
    std:: cout << elements [10000];
    return 0;
}

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

【问题讨论】:

  • 下标运算符从未进行过边界检查,越界索引一直是未定义的行为
  • 行为未定义;没有预期的行为。
  • @molbdnilo 意外和未定义是不同的东西
  • 对问题投反对票的人应该说明原因并提供帮助。如果用户在投反对票之前不能离开任何 cmets,我建议跳过投反对票。

标签: c++ c++14 stdvector


【解决方案1】:

那么第 10000 个元素是如何存储在这里的呢?

元素存储在向量中。它被“存储”在与向量无关的一段内存中。

这里的预期行为不是“分段错误”吗?

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

但以上运行成功。

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

      您可以在 valgrind 下运行它,然后查看错误:

      ==31899== 大小为 4 的无效写入 ==31899== at 0x400B30: main (in a.out) ==31899== 地址 0x5a21c80 在竞技场“客户端”中大小为 4,194,128 的未分配块内是 39,920 字节 ==31899== ==31899== 大小为 4 的读取无效 ==31899== 在 0x400B47:主要(在 a.out) ==31899== 地址 0x5a21c80 在 arena "clien

      中大小为 4,194,128 的未分配块内是 39,920 字节

      t" ==31899==

      您也可以尝试使用.at() 代替[]。 在这种情况下会抛出 out_of_range 异常。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-19
        • 1970-01-01
        • 2014-10-13
        • 1970-01-01
        • 2021-11-14
        • 1970-01-01
        相关资源
        最近更新 更多