c++ - 返回指向局部函数变量的指针

标签 c++ visual-c++

<分区>

Possible Duplicate:
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)。这种行为是否对所有编译器都很常见?编译器如何允许我使用指向局部函数变量的指针来访问它指向的值,尽管函数返回时该变量已失效?

最佳答案

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

您的地址在堆栈上,因此始终可以访问。根据您在两者之间进行的调用,该值可能仍然存在或不存在。所以在简单的情况下,您可以取回值(value),在更复杂的情况下您不会。它甚至可能有时有效,有时无效。

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

关于c++ - 返回指向局部函数变量的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8708803/

相关文章:

windows - vcvarsall.bat 和 bin/vcvars32.bat 有什么区别?

c++ - 无法从 Main 创建对象

c++ - range-for循环中的访问索引

c++ - 字符串 Vector push_back 在类里面失败

c++ - 我应该在带有模板的主题观察者模式中使用动态转换吗

c++ - 如何获取数据 IWbemClassObject **

opencv - 使用OpenCV3的视频中的人脸识别会产生未处理的异常(opencv_core310.dll)

c++ - int 测试(无符号整数 i = -1);为什么编译器不生成警告?

c++ - CEF 在调用特定 DLL 中的函数时崩溃

windows - Windows 应用程序上的不规则套接字错误 (10054)