【问题标题】:Returning pointer to local function variable [duplicate]返回指向局部函数变量的指针[重复]
【发布时间】:2023-04-09 22:25:01
【问题描述】:

可能重复:
Returning the address of local or temporary variable
Can a local variable's memory be accessed outside its scope?

我知道我不应该返回指向局部函数变量(局部堆栈变量)的指针,因为当函数返回时,变量将无效并且堆栈将被清理,除非我将这些变量设为静态或在堆上分配它们。

以下代码证明:

const char* v1() {
   return "ABC";
}

const char* v2() {
    string s = "DEF";
    return s.c_str();
}

const char* v3() {
    static string s = "JHI";
    return s.c_str();
}

cout << v1() << endl; // Output: ABC
cout << v2() << endl; // Output: garbage (♀   ╠╠╠╠╠╠╠╠)
cout << v3() << endl; // Output: JHI

但是,我返回了指向原始局部函数变量的指针,尽管它不是静态的,但我能够获取它的值,如下面的代码所示:

int i1() {
    int i = 5;
    return i;
}

int* i2() {
    int i = 6;
    return &i;
}

int* i3() {
    static int i = 7;
    return &i;
}

cout << i1() << endl;  // Output: 5
cout << *i2() << endl; // Output: 6 !!
cout << *i3() << endl; // Output: 7

编译器只警告我正在返回局部变量或临时变量的地址 (Visual C++ 2008)。这种行为是否对所有编译器都通用?编译器如何允许我使用指向局部函数变量的指针来访问它指向的值,尽管函数返回时该变量无效?

【问题讨论】:

  • 它的值恰好保留在内存中的同一位置。这工作的事实要么是意外,要么是您在“调试”模式下编译的结果。我不确定问题是什么——你已经知道你不应该这样做。听听编译器发出的警告!

标签: c++ visual-c++


【解决方案1】:

你返回一个地址。返回地址是有效的 - 总是。但在你的情况下,你也取消引用它。这是未定义的行为。从理论上讲,对于未定义的行为,任何事情都可能发生。编译器甚至可以嵌入代码来格式化您的硬盘。实际上,它会在没有任何检查的情况下取消引用地址。如果它仍然可以访问,它将返回该地址的值,否则会导致访问冲突。

您的地址在堆栈上,因此始终可以访问。根据您在两者之间进行的调用,该值可能仍然存在或不存在。所以在简单的情况下,你会得到价值,在更复杂的情况下你不会。它有时甚至会起作用,有时却不起作用。

有关更多信息,您应该阅读有关如何在汇编程序中进行函数调用的一些信息,以了解编译器在堆栈上所做的事情(放置参数、返回地址、放置局部变量、返回时的堆栈清理、调用约定) .

【讨论】:

    【解决方案2】:

    它可以从堆栈中删除,因为它是本地的,但该值将保留到另一个覆盖它。 这是 c++ 不安全的语言,你可以做很多奇怪的事情

    【讨论】:

      猜你喜欢
      • 2016-10-25
      • 2020-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-14
      • 1970-01-01
      相关资源
      最近更新 更多