【问题标题】:How c++ new statement work?c++ new 语句如何工作?
【发布时间】:2014-05-25 16:10:32
【问题描述】:

为什么最后一个“cout”行总是输出“16”?? 在我的机器上,sizeof(int) 是 4。

#include <iostream>

using namespace std;

int main() {
  int *pint1 = new int;
  int *pint2 = new int;
  cout<<pint1 <<endl;
  cout<<pint2 <<endl;

  cout<<(int)pint2 - (int)pint1 <<endl;
}

【问题讨论】:

    标签: c++


    【解决方案1】:

    因为在您的平台上,malloc 地址默认是 16 字节对齐的。而 new 只是使用 malloc。

    结果很大程度上取决于使用的平台和系统上的 malloc 实现。但大多数系统会打印 16。

    【讨论】:

      【解决方案2】:

      由于内部编译器行为。它可以在前一个内存块之后分配下一个内存块。

      但这完全是实现选项。编译器可能每时每刻都停止这样做。

      顺便说一句,我的编译器(ubuntu 上的 gcc)打印 32

      0x12b2010
      0x12b2030
      32
      

      【讨论】:

        【解决方案3】:

        可能是由于对齐的原因,还有一个事实是,每个用 new 或 malloc 分配的内存块都必须记住自己的大小,因此比您请求的要大。 “额外”信息通常在指针返回之前

        【讨论】:

          【解决方案4】:

          你不能对pint1pint2在堆栈上的位置做出任何假设(指针堆栈分配的,但它们指向的东西是在堆上分配的),因为它是C++ 标准未指定。它们当然不必在连续的内存中。

          例如,使用指针算法pint1 + 1 不会,一般来说,让你登陆pint2

          如果您编写了int* pint = new int[2];,则可以使用指针算法。然后,pint + 1 指向第二个元素。

          为了保持标准,使用

           cout << (std::ptrdiff_t)(pint2 - pint1) << endl;
          

          将是首选,我明确使用(std::ptrdiff_t)。如果您在 64 位架构(例如 Win64、MSVC)上使用 32 位 int,您当前编写它的方式可能会给您未定义的行为

          (别忘了delete分配的内存)。

          【讨论】:

          • pint1pint2 不在堆栈中。它们是堆分配的。
          • 这就是我的意思,对不起。但是示例代码打印出指针值的差异,它们指向堆分配的对象。
          • 我同意。事实上,打印出取消引用的值将是未定义的行为,因为数据未初始化。
          • 表达式pint2 - pint1 本身就是未定义的行为。你不能减去两个不相关的指针; § 5.7 第 6 段“除非两个指针都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,否则行为是未定义的。”
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-08-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-13
          相关资源
          最近更新 更多