gpt4 book ai didi

c++ - 静态函数中的静态变量可以移动到内存中的新地址吗?

转载 作者:行者123 更新时间:2023-11-30 01:23:49 28 4
gpt4 key购买 nike

我刚刚升级到第三方库的新版本(Qt 5.0 的 QtPropertyBrowser)。升级在我的应用程序中导致了一个新错误,我设法跟踪到库中的静态函数。该函数包含一个静态变量,该变量在第一次调用该函数时被初始化。我在初始化后复制了该变量的内存位置,并且如预期的那样发现,在多次后续调用中,该变量仍保留在同一内存位置。然后在随后的函数调用中,我注意到静态变量中的内存位置和数据发生了变化(导致我的程序出现错误)。

代码看起来像这样:

class ClassA
{
//....
};

class ClassB
{
public:
ClassA* ptrMember;
};

static ClassA *theFunction()
{
static ClassB statVar = {0};
if(!statVar.ptrMember)
statVar.ptrMember = new ClassA();
return statVar.ptrMember;
}

我发现在多次调用 theFunction() 时,存储在 &statVar 中的地址始终保持不变,但在随后的调用中,&statVar 中的地址 不同,statVar.ptrMember 为空。

我没想到这是可能的!有什么想法吗?

最佳答案

看起来您已经在头文件中定义了函数,并且包含在许多.cpp 文件中(每个.cpp文件定义一个翻译单元)。

由于函数被声明为static,每个翻译单元都有自己的版本以及static 变量。这就是为什么当你从不同的翻译单元调用函数时,静态变量的地址是不同的。只要您从同一个翻译单元调用它,您就会看到相同的地址。

请注意,特定翻译单元的地址将保持不变。只是每个翻译单元都有自己的静态变量版本,因此地址不同;您不再访问同一个变量,它们是具有相同标识符的不同变量。


The problem is that this is all defined in a third party library and I need to call it from both a dll and an exe without the static variable getting reinitialized. Is there any way that I can take care of the problem without altering the code in the library? I am currently using the library as a .lib. Would the problem go away if I compiled it as a .dll instead?

为避免静态函数(因此是静态变量)的多个版本,您需要从同一个翻译单元调用它。为此,您可以使用代理 来调用该函数。也就是说,不是直接调用函数,而是调用一个代理(定义在单个翻译单元中,没有更多的版本)。

  • 在 header 中声明代理:

    //proxy.h
    ClassA *proxy_of_theFunction();
  • 在实现文件中定义代理:

    //proxy.cpp
    ClassA* proxy_of_theFunction()
    {
    return theFunction(); //call the actual function
    }

调用proxy_of_theFunction。那应该可以解决您的问题。

由于 proxy_of_theFunction不是 static(并且它是在 proxy.cpp 中定义的),它只有一个版本;没有其他版本。因为只有一个代理可以从中调用 theFunction(),所以每次都会调用相同版本的 theFunction,因此您会看到相同 版本的 static 变量用于每次调用。 :-)

关于c++ - 静态函数中的静态变量可以移动到内存中的新地址吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14464373/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com