7

我在一次采访中遇到了这个代码。

int main()
{
    int **p;
    p = (int **) new int(7);
    cout<<*p; 
    return 0;
}

我期待在 *p 出现一些运行时错误。但是当我运行代码时,它成功执行并输出“0x7”。有人可以解释一下这是如何工作的。谢谢。

4

5 回答 5

5

除非给你一些额外的限制,否则正确的答案是以上都不是。基本上,代码正在分配一个int并解释该内存,就好像它是一个int*(通过一个reinterpret_cast)。第一个问题是,作为 a reinterpret_cast,结果在一般情况下是未指定的,并且如果 的大小int小于int*(认为是 64 位架构)的大小,则结果是未定义的行为,因为您正在读取超出分配的大小new称呼。

于 2012-04-15T18:40:02.110 回答
4

您创建一个新的 int 并将其初始化为值 7。

int *x = new int(7);

您比将其转换为指针(例如内存地址 7 或 0x07)

int **p = (int**) new int(7);

然后你用 cout 显示这个地址。

*p is equal to (int*)7

它是一个值为 7 的指针。

于 2012-04-15T18:27:20.130 回答
0
new int(7);

int为其值为 is的 an 分配内存7并返回指向它的指针。

int **p = (int **) new int(7);

告诉编译器将该内存解释为int**.

cout << *p;

告诉编译器在地址*p处是一个int *并且输出它的值。值为0x07。(它将 int7视为地址)。额外的取消引用会导致崩溃(准确地说,是未定义的行为)。

于 2012-04-15T18:30:52.160 回答
0
int main()
{
    int **p;                  // declare pointer to pointer called p
    p = (int **) new int(7);  // new allocates integer initialized to value of 7 and returns a pointer.  Cast the pointer to a point to pointer.  p now represents a pointer to a pointer with contents of 0x7.  If you called **p you would get the contents at address 0x7.
    cout << *p; // dereference p, this yields a pointer, which is an int of value 0x7.
}

这个问题很可能是为了测试您对指针的了解,但似乎不太实用。

于 2012-04-15T18:37:25.267 回答
0
int main()
{
    int **p = (int **) new int(7);
    cout << *p;
}

因此,new int(7)分配sizeof(int)内存字节并返回指向它的指针。假设内存恰好位于地址 X。然后 X 被强制转换(int**)并存储在p.

*p取消引用int**,这意味着它将int地址处的值 7 解释Xint*.

  • 如果sizeof(int*)大于sizeof(int),则作为 anint*读取将超出分配的缓冲区new- 无论数据类型和任何重新解释如何,总是未定义的行为。

  • 如果大小相同,CPU 将尝试读取包含整数 7 的内存int*- 这通常会产生 value int*(7),但查看标准 5.2.10.5:

整数类型或枚举类型的值可以显式转换为指针。* [脚注:转换值为 0 的整数常量表达式 (expr.const) 始终会生成空指针 (conv.ptr),但会转换发生的其他表达式具有零值不需要产生空指针。--- end foonote] 转换为足够大小的整数(如果实现中存在这样的整数)并返回相同指针类型的指针将具有其原始值;指针和整数之间的映射是由实现定义的。

因此,整数值保证转换为某个指针值 - 没有未定义的 - 但该值是实现定义的。尽管如此,作为一个可逆操作, 7 极有可能int产生一个int*值为 7 的值——这解释了观察到的输出“7”的行为。

  • 如果指针大小小于int大小,它将读取int值的一部分并将其解释为指针。根据字节顺序,切片可能是 0 或 7 甚至是其他值,但同样,int它必须可转换为将显示的某个指针值。
于 2012-04-16T05:33:57.720 回答