【问题标题】:How will this code affect the memory management? [duplicate]此代码将如何影响内存管理? [复制]
【发布时间】:2017-03-27 11:59:26
【问题描述】:
#include<iostream>
using namespace std;
int main()
{
    char  a[]="robert";
    cin>>a;
    cout<<a;
}

因此,a 的大小现在固定为 7 位,这很直观。现在,如果我将“qwertyuiop”之类的内容读入大于 7 位的“a”中,则预计会显示溢出。然而,没有这样的事情发生,它正常打印输出。这是怎么回事?

【问题讨论】:

  • 没有a 的大小是七个字节。而且 C++ 没有边界检查。越界写入会导致未定义的行为。故事结束,真的。
  • @Someprogrammerdude char a[] 不是用参数的大小定义一个数组吗?
  • @Alex 字符串中的六个字母,加上终止符。一个由七个字符组成的数组。
  • @Someprogrammerdude 你是完全正确的。我的问题是char a[]="robert"char a[]="robert barateon" 之间是否有区别?这是否意味着a 将具有适当字符串的大小?
  • 将更多的数据写入数组而不是它可以容纳的数据会导致 UNDEFINED 行为。一种可能的表现是程序崩溃。另一种可能的表现是没有任何可观察到的症状。在适当的硬件支持下,该程序甚至可以电死程序员 - 因此通过幸存的程序员增加对未定义行为的真正含义的平均理解。

标签: c++


【解决方案1】:

越界写是一种未定义的行为

在这种情况下看起来没问题,但如果……会发生什么

#include<iostream>
using namespace std;
int main()
{
    char  a[5];
    char  b[7];
    cin >> a;
    cin >> b;
    cout << a << endl;
}

输入:

金刚
猎猴人

输出:

金猴猎人

他们搞混了!

你应该小心 C++ 中的数组,如果你尝试写越界,它可能不会有明显的效果。

【讨论】:

    【解决方案2】:

    操作系统(在处理器的帮助下)定义了允许您的应用程序读取/写入的内存区域。当您阅读超出预期的内容时,处理器会触发一个硬件异常,该异常会被您的操作系统捕获,这会触发您的应用程序终止。

    但是,在数组外部读取并不一定会在应用程序边界之外读取(例如,您可以写入/读取到您自己代码的另一个变量)。例如,在内存区域的末尾,程序堆栈通常以相反的顺序排列。

    C++ 将超出数组范围的读取/写入指定为未定义行为。在这种情况下,它可能会以“类似随机”的方式崩溃或不崩溃。

    【讨论】:

    • 这是一个相当老套的答案;几十年来,我们已经拥有虚拟内存。处理器不会在这里触发任何异常。
    • 您能进一步解释一下您的观点吗?我显然知道虚拟内存、表管理、重新定位等。但据我所知,仍然存在内存保护,由操作系统管理并由 CPU 执行。
    • 操作系统管理虚拟内存页面,而不是处理器。当然操作系统是由处理器实现的,但用户的程序也是如此,所以我们不讨论这个。
    • @BoundaryImposition:虚拟内存是通过将部分内存移动到外部存储(通常是 HD)来模拟比可用内存更多的内存。这里我说的是内存保护(en.wikipedia.org/wiki/Memory_protection),用于保护每个进程免受其他进程的影响。在我的解释中,我引入了这个概念来解释为什么读取悬空指针可能会或不会终止应用程序。
    • 它不需要是“专利说明书”(?)是真实的。但是,我发现并承认虚拟地址转换是在硬件中执行的,这是我不知道的。
    猜你喜欢
    • 2011-03-13
    • 2011-07-16
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    • 2018-12-22
    • 2016-03-11
    • 2012-10-14
    • 1970-01-01
    相关资源
    最近更新 更多