【问题标题】:C++: Memory allocationC++:内存分配
【发布时间】:2015-02-10 11:19:28
【问题描述】:
#include <iostream>
using namespace std;

int main()
{
    int a[100],n;
    cout<<&n<<" "<<&a[100]<<endl;
    if(&n!=&a[100])
    {
         cout<<" What is wrong with C++?";
    }
}

它打印 n 和 a[100] 的地址相同。但是当我比较 if 循环中的两个值时,它说它们都不相等。

这是什么意思?

当我改变 n 的值时,a[100] 也会改变,所以这不意味着 n 和 a[100] 相等。

【问题讨论】:

标签: c++ memory-management


【解决方案1】:

首先,让我们记住没有a[100]。它不存在!如果你试图访问a[100] 的“值”,那么根据名为 C++ 的抽象机器,任何事情都可能发生。这包括炸毁太阳或将头发染成紫色;现在,我喜欢我现在的头发,所以请不要!

无论如何,您正在做的是使用数组的“one-past-the-end”指针。只要你不取消引用它,你就可以获取这个指针,它是一种假指针。

它仅因为“101st 元素”将是数组的“末尾之一”才可用。 (关于是否允许您写 &amp;a[100] 而不是 a+100 以获得这样的指针存在争议;我属于“不”阵营。)

但是,这仍然没有说明将它与一些完全不同的对象的地址进行比较。您不能假设内存中局部变量的相对位置。你根本不知道n 相对于a 将住在哪里。

您观察到的结果是您的程序所表现出的未定义行为的不可预测、不可靠和无意义的副作用,这是由编译器优化和数据局部性共同引起的。

【讨论】:

  • 我认为标准说获取过去一个数组结束元素的地址是有效的(IIRC end() 有时会这样做)。那么行为不会被定义吗?
  • @FrédéricHamidi:是的,获取地址没问题。如果你写&amp;a[100]而不是(a+100)(我在“不”阵营),是否定义了它存在争议,但这是顺便说一句。但是他试图合理化那个过去的指针是否与n的地址相同,这是没有意义的。
  • @FrédéricHamidi:它比填充/对齐更基本。局部变量的相对位置是完全未指定的。
  • @FrédéricHamidi:感谢您的 cmets,因为他们让我意识到我的答案集中在 OP 实际上没有做的事情上......
  • 请注意,std::less&lt;&gt;std::greater&lt;&gt;可以用于建立不相关指针的总排序。 (§ 20.8.5/8)
【解决方案2】:

对于数组声明 int a[100],数组索引从 0 开始到 99,当您尝试访问超出其范围的第 101 个元素的地址时,可能与下一个成员重叠(在您的情况下,它的变量 @ 987654324@) 在堆栈上。但是它的未定义行为。

【讨论】:

    【解决方案3】:

    如果这里的事实是规范中的相关文本,请稍加说明 等式运算符 (==,!=)

    可以将指向相同类型对象的指针与“直观”的预期结果进行比较:

    来自 C++11 标准的第 5.10 节:

    可以比较相同类型的指针(指针转换后)是否相等。相同类型的两个指针在 > 且仅当它们都为 null、都指向同一个函数或 > 都表示相同的地址(3.9.2)时才比较相等。

    (省略了比较指向成员和/或 空指针常量 - 它们继续沿着同一行 'Do > 我的意思':)

    • [...] 如果两个操作数都为空,则它们比较相等。否则,如果只有一个为空,则它们比较不相等。[...]

    最“显着”的警告与虚拟有关,这似乎也是合乎逻辑的事情:

    • [...] 如果其中一个是指向虚成员函数的指针,则结果未指定。否则当且仅当它们比较相等 它们将引用同一个最衍生对象的同一个成员 (1.8) 或相同的子对象,如果它们被取消引用 关联类类型的假设对象。 [...]

    也许问题可能是 int 的数组与 int 不同!

    【讨论】:

      【解决方案4】:

      通过编写&amp;a[100],您正在调用未定义的行为,因为数组a 中没有索引为100 的元素。为了安全地获得相同的地址,您可以改为编写a+100(或&amp;a[0]+100),在这种情况下,您的程序将是明确定义的,但无法预测或依赖于任何实现是否会成立 if 条件。

      【讨论】:

        猜你喜欢
        • 2015-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多