【问题标题】:How I am able to put more elements in an array whose size is fixed? [duplicate]如何将更多元素放入大小固定的数组中? [复制]
【发布时间】:2021-09-17 08:30:12
【问题描述】:

当我在 C++ 中声明一个数组时,在我的计算机上,比如说这个

int mynum[3];
mynum[0]=1;
mynum[1]=2;
mynum[2]=3;

mynum 是一个可以容纳 3 个元素的数组, 现在当我添加这一行时

mynum[3]=4;

它在 Windows 和 Ubuntu 终端上崩溃(堆栈粉碎检测到未知终止的核心转储) 但是当我使用时,

mynum[4]=56;
mynum[5]=34;
mynum[6]=23;

它没有给出任何错误(当我使用以上三行代替 mynum[3] 时) 为什么会这样?

【问题讨论】:

  • C++ 没有对普通数组进行边界检查。越界会导致未定义的行为。如果它看起来有效,那么你“un很幸运”。
  • @Someprogrammerdude 更重要的是,未定义的行为(遗憾的是)默认情况下不检查。这有很多缺点,这就是为什么它默认不启用的原因,但至少 clang 工具链具有可以检测此类错误的消毒剂。

标签: c++ arrays crash


【解决方案1】:

超出数组范围的写入具有未定义的行为。如果那部分内存仍在数据段中,它可能会偶然工作,并且可能会发生惊人的崩溃。在任何情况下,你都不应该为这个动作假设任何行为,你的程序也不应该依赖它。

【讨论】:

  • “如果那部分内存仍在数据段中,t 可能会偶然工作”,在此之前编译器必须翻译它,即使代码没有意义。编译器也可以将 OP 代码等同于以下代码:int main() {}
  • @463035818_is_not_a_number 如果编译器可以检测到这样的 UB 并完全删除所有代码,为什么它会这样做而不是抛出错误?它肯定是一个实现细节,但为什么任何实现者会选择它而不是错误消息呢?当我想到未定义的行为时,它甚至是编译器都没有意识到的,它只是盲目地将你写的东西翻译成机器代码,即使它被破坏和错误。如果它检测到它并决定做任何事情,我会称之为编译器错误。
  • 因为如果编译器可以假设 UB 不会发生并删除它发生的路径,它使得编写优化器成为可能(或者更容易)。请参阅本页底部的链接,其中 LLVM 博客讨论了 UB 和优化之间的交互 ​​- en.cppreference.com/w/cpp/language/ub
  • @Kaihaku 我指的是什么符合标准,你可以依靠什么,你得到什么保证。当代码有 UB 时:无。恕我直言,一旦您的代码具有 ub,实现细节就没有那么重要了。实际上我的观点是,应该区分代码,它是程序的抽象描述,以及关于访问真实内存等的程序集
  • @RichardCritten 我真的很好奇,你如何在不知道它的 UB 的情况下删除发生 UB 的路径?它可能发生的唯一方法是如果它不是故意的,这与“当 x 然后 y”不同。
【解决方案2】:

这是因为数组的大小是固定的,不能修改,当你试图访问mynum[4]时,这超出了你分配的数组大小,你试图到达一个非法的段(可以分配给其他用途)。

如果您需要大小也是动态的类似数组的存储(即在内存中连续),您可以使用std::vector

【讨论】:

    猜你喜欢
    • 2015-04-14
    • 1970-01-01
    • 2015-07-28
    • 2018-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    • 1970-01-01
    相关资源
    最近更新 更多