【问题标题】:Pointers and literals constant [duplicate]指针和文字常量 [重复]
【发布时间】:2013-08-08 17:30:45
【问题描述】:

我有一个不应该工作的代码,但它可以工作。你能告诉我为什么吗?

#include <iostream>

void f ( int** a, int b ) ;

int main (void) {

    int ** a ;
    a = new int* () ;  

    f(a,5) ;

    std::cout << **a << std::endl ;

    return 1 ;

}

void f ( int** a, int b ) {

    *a = &b ;

}

我声明了一个指向名为a 的指针,我为其分配一个指针,然后将它传递给f()。另一个f() 参数是一个常量字面量,因此它应该没有在main() 中分配静态内存,因此它不应该存在于f() 之后。在f() 内部,我将局部变量b 的内存方向分配给f() 复制的main 上的指针,然后当main() 执行f() 时,所有局部变量都应该被删除然后继续,所以@ 987654332@ 应该指向垃圾,或者什么都没有,但它没有并指向 5,已经删除的值强>b

真正发生了什么?为什么这段代码有效?

【问题讨论】:

  • 它调用未定义的行为,未定义的行为是未定义的。
  • 当他们说这是一种未定义的行为时,这意味着它可以通过正确的行为让你大吃一惊,或者有时它不会奏效。
  • 它不起作用;它具有未定义的行为。当您销毁它包含的对象时,内存不一定会消失,因此悬空指针可能(或可能不会)仍然看到曾经存在的值。如果启用它们,您应该会收到编译器警告。
  • @MikeSeymour 我正在使用 -Wall -pedantic 进行编译,编译器不会抱怨。我应该使用哪些标志。
  • @GonzoRI:实际上,也许你不会收到警告。大多数流行的编译器都会诊断return &amp;b;,但可能是*a 的赋值超出了编译器的分析能力。

标签: c++ pointers literals


【解决方案1】:

看似有效,实际上无效。

*a 指向栈上的地址。

当你打印**a时,实际打印的是栈上某个地址的内容。 (调用函数f时包含5的地址)。

但是,由于堆栈不会根据您的代码发生太大变化,因此值 5 仍会写入特定地址,因此会打印值 5。 如果你调用其他函数然后打印 **a 你可能会得到不同的值。

【讨论】:

    【解决方案2】:

    在您的情况下,内存不会立即被覆盖。这是未定义的行为,它可能不会一直表现相同。每个编译器可能会以不同的方式处理它,您可能会在不同的平台上看到不同的结果,甚至在发布与调试模式下。

    【讨论】:

      猜你喜欢
      • 2014-02-23
      • 1970-01-01
      • 2012-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-23
      • 1970-01-01
      • 2021-04-19
      相关资源
      最近更新 更多