返回指向局部函数变量的指针 [英] Returning pointer to local function variable

查看:111
本文介绍了返回指向局部函数变量的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

返回本地或临时变量的地址

可以在其范围之外访问局部变量的内存吗?

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

I know that I should not return pointers to local function variables (local stack variables) because when the function return, the variables will be invalid and the stack will be cleaned up unless I made these variables static or allocated them on heap.

以下代码演示了这一点:

The following code demonstrates that:

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

但是,我返回了指向原始本地函数变量的指针,得到它的值,尽管它不是静态的,如下面的代码所示:

However, I returned pointer to a primitive local function variable and I was able to get its value although it is not static, as the following code shows:

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

The compiler only gives me warning that I am returning address of local variable or temporary (Visual C++ 2008). Is this behaviour common to all compilers and how the compiler allows me to use pointer to a local function variable to access the value it points to although the variable is invalidated when the function return?

推荐答案

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

you return an address. Returning an address is valid - always. But in your case, you also dereference it. This is undefined behavior. Theoretically, for undefined behavior, anything can happen. The compiler is even allowed to embed code to format your hard-disc. Practically it will dereference the address without any checks. If it is still accessible, it'll return the value at that address otherwise it'll cause an access violation.

您的地址在堆栈中,因此它始终是无障碍。根据您之间的调用,该值可能仍然存在或不存在。因此,在简单的情况下,您将获得价值,而在更复杂的情况下,您将无法获得价值。

Your address is on the stack, so it is always accessible. Depending on the calls you made in between, the value might still be there or not. So in simple cases, you get the value back, in more complicated cases you won't. It may even work sometimes and sometimes it does not.

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

For more information, you should read some information on how function calls are made in assembler to understand what the compiler is doing there on the stack (placing parameters, return address, placing local variables, stack cleanup on return, calling conventions).

这篇关于返回指向局部函数变量的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆