【问题标题】:warning C4172: returning address of local variable or temporary [duplicate]警告 C4172:返回局部变量或临时地址的地址 [重复]
【发布时间】:2011-04-13 23:59:38
【问题描述】:

可能重复:
Pointer to local variable

我在这个网站上阅读了很多关于同样问题的其他主题,我知道这很常见。但我想我很愚蠢,无法弄清楚正确的方法。所以,我为这些问题中的另一个问题道歉,我希望有人能给我一个简单的解决方案和/或解释。

这是完整的代码:

Main.c

#define WIN32_LEAN_AND_MEAN

#include <Windows.h>
#include <stdlib.h>
#include <tchar.h>


LPTSTR GetApplicationPath ( HINSTANCE Instance );


int APIENTRY _tWinMain ( HINSTANCE Instance, HINSTANCE PreviousInstance, LPTSTR CommandLine, int Show )
{
    LPTSTR sMessage = GetApplicationPath ( Instance );

    MessageBox (
        NULL,
        sMessage,
        _T ( "Caption!" ),
        MB_OK
    );

    return 0;
}


LPTSTR GetApplicationPath ( HINSTANCE Instance )
{
    _TCHAR sReturn[MAX_PATH];

    GetModuleFileName ( (HMODULE) Instance, sReturn, MAX_PATH );

    return sReturn;
}

【问题讨论】:

    标签: c compiler-warnings


    【解决方案1】:

    现在,您正在返回一个自动(堆栈)数组的地址。这是总是错误的,因为一旦函数结束,内存的生命周期也会结束。

    你需要使用malloc(和free),或者其他动态分配。例如:

    _TCHAR *sReturn = malloc(sizeof(_TCHAR) * MAX_PATH);
    

    我省略了错误检查。然后稍后,调用代码应该释放它。在_tWinMain 中的MessageBox 之后:

    free(sMessage);
    

    【讨论】:

    • 已修复,谢谢。显然,我必须等待 9 分钟才能接受,但我会的。再次感谢。 :)
    • 只需要添加一个演员表,我相信你和每个人都已经知道这一点:_TCHAR * sReturn = (_TCHAR *) malloc ( sizeof ( _TCHAR ) * MAX_PATH );
    • @guitar,你确实不需要需要在 C 中进行转换。这可能意味着你真的在使用 C++。
    • 没有它编译很好,只是在 Visual Studio 中加了下划线并显示错误,所以我认为最好有它。
    • @guitar:演员阵容被认为是非常糟糕的风格有几个原因。
    【解决方案2】:

    改变

     _TCHAR sReturn[MAX_PATH];

    在你的“GetApplicationPath”中

     静态 _TCHAR sReturn[MAX_PATH];

    如果只有一个线程要调用 GetApplicationPath(),那么动态分配这个字符串是多余的。将局部变量标记为静态会使用全局变量为其分配空间,这样当您退出函数时,空间就不会被踩到。

    【讨论】:

    • 除非您同时针对堆栈和堆使用进行优化,否则这样做没有任何意义。通常没有人会费心去优化堆栈的使用,而且不假设线程情况会更安全。
    【解决方案3】:

    考虑修改:

      LPTSTR GetApplicationPath ( HINSTANCE Instance )  
    

    类似

      void GetApplicationPath ( HINSTANCE Instance, LPTSTR str )  
    

    这将消除返回局部变量的需要。

    【讨论】:

    • 你可以这样做,但GetApplicationPath 应该只使用LPTSTR,因为你只是将字符写入该位置,而不是设置调用者的变量。此外,它必须采用长度参数或文档,它必须是MAX_PATH
    • @Matthew - 我修复了你提到的指针问题。谢谢。我在想我会把你提到的 MAX_PATH 问题留给用户想象。参数确实可以是他们喜欢的任何东西(例如 char pathname[MAX_PATH])。干杯
    【解决方案4】:

    警告说明了一切。在函数GetApplicationPath 中,您将返回函数本地的sReturn。函数返回后局部变量不复存在,函数返回后对局部变量的引用不正确。

    要克服这个问题,您可以将sReturn 的空间动态分配为:

    sReturn = malloc(sizeof(_TCHAR) * MAX_PATH);
    

    【讨论】:

    • 在 C 中,不应强制转换 malloc 的返回值。当忘记包含“stdlib.h”时,这可能会在 64 个拱门上丢失您的地址位... 转换 malloc 是 C++ 习惯。在那里你需要这样做,但无论如何你通常应该使用new
    猜你喜欢
    • 2019-06-15
    • 1970-01-01
    • 2022-01-17
    • 2013-01-30
    • 2023-03-11
    • 2011-10-17
    • 2021-04-28
    • 2013-06-23
    相关资源
    最近更新 更多