在 C++ 中删除其类的实例后,分配给 cpp 中定义的全局静态变量的内存是不是被释放?
Posted
技术标签:
【中文标题】在 C++ 中删除其类的实例后,分配给 cpp 中定义的全局静态变量的内存是不是被释放?【英文标题】:Is the memory allocated to a global static variable defined in cpp freed up after a instance of its class is deleted in C++?在 C++ 中删除其类的实例后,分配给 cpp 中定义的全局静态变量的内存是否被释放? 【发布时间】:2015-03-12 20:54:53 【问题描述】:我有一个类,其方法在 example.cpp 文件中定义,类在 example.h 中定义。在 example.cpp 文件中定义了一个静态全局指针。 (我需要将此指针定义为 .cpp 中的静态全局指针,因为它在裸机系统上运行的静态中断服务例程中被调用。)我想知道 何时删除此类的实例,是分配给这个静态全局指针的内存,在类之外定义(在 cpp 文件中作为静态全局变量),也释放了?我担心内存泄漏问题。 (请不要用智能指针提出任何建议,谢谢)
// example.cpp
#include <example.h>
static example* ptr;
example::example() prt = this;
example::~example()
// example.h
class example
public:
example();
virtual ~example();
int a;
;
//main.c
void main(void)
while(1)
example eg1;
delete &eg1;
//Has all the memory allocated to eg1 been freed up including the global static variable(a pointer)?
我知道一旦对象被删除,对象内部的 (int a) 肯定会被释放,但是分配给全局静态指针本身的内存(静态示例 * ptr)也会被释放吗? (我假设)如果类的所有实例都没有共享静态全局变量,它是否实际上为这个静态全局变量分配了内存,但在删除实例后没有释放它?会不会导致内存泄露?
这是我第一次在这里提出问题。如有不清楚之处,请提前道歉。
【问题讨论】:
谁不只使用单例设计模式? new 和 delete 必须成对使用,现在你明白你的代码有什么问题了吗? 我相信您已经意识到您的delete &eg1
声明既是危险的错误,也是完全没有必要的......
【参考方案1】:
首先,如果你运行你发布的代码,你会得到以下结果:
malloc: *** error for object 0x7fff560a8830: pointer being freed was not allocated
这是因为您删除了&eg1
,而没有先使用new
在堆上为其分配内存。
其次,析构函数/delete
只会清理与example
对象关联的内存。它没有义务清理static example* ptr
。
从另一个角度来看,析构函数和delete
旨在清理动态分配的数据,即存在于堆上的数据,而不仅仅是当前函数调用的堆栈上。相比之下,static example* ptr
是一个全局变量,它存在于全局数据段上,与堆和堆栈分开。
因此,您可以看到delete
和example
对象的析构函数不会释放分配用于存储指针本身的内存,因为它们都没有权限这样做。
编辑 ------------------
正如其他人所说,static
变量在程序的整个生命周期内都存在,因此在程序终止之前它们不会被删除。
这里有很多东西可以收集! static
起初可能会让人感到困惑,但深入了解它会大有帮助。
【讨论】:
【参考方案2】:任何声明为static
的东西都会在程序的生命周期中存在。它在第一次可能使用之前构建,并在程序终止期间的不完全指定的时刻销毁(即在main
返回或exit
被调用之后)。
此外,销毁(非智能)指针从不会破坏指针指向的东西。如果要释放指针指向的资源,则必须在指针上显式调用 delete
。 (或者使用智能指针。做。他们更好。)
【讨论】:
感谢您的回答,但在这里我可能会误导您。我对指向的指针的内存不感兴趣,但实际上是分配用于存储指针本身的内存。我只是稍微修改一下代码以使其更清晰。 @TyL:这是我第一段的主题。根据定义,任何静态事物的生命周期都是程序的生命周期。 您是说静态全局变量也与该类的所有实例共享吗? (我认为它只有在类内部定义为成员而不是类外部时才能共享)。否则,静态变量将不知道我将创建多少这个类的实例?你认为我的 main.c 中的 while(1) 循环会导致内存泄漏吗? @tyl:只有一个静态全局变量。为什么你认为它会与类的实例有关?它只是一个没有外部链接的全局定义。 好的。我现在明白了。非常感谢!!!!!!!我一直认为一旦创建它的实例就会创建它......【参考方案3】:一般来说,静态全局变量不是成员变量,所以当一个类被分配或删除时,对静态全局变量没有影响,除非类成员显式地为静态全局变量分配或释放内存。
在您的示例中,您只是将指针分配给全局变量,而不是分配新内存。因此,您无需显式释放它。
另外,你不需要在 main() 中调用 delete,因为 eg1 是一个局部变量。 main 返回时,会自动调用 eg1 的析构函数。
【讨论】:
谢谢。这真的很有帮助。您是说静态全局变量也与此类的所有实例共享吗? (我以为只有在类中而不是类外定义时才能共享) 类的所有实例都可以访问静态全局变量,并且每次创建新的示例对象时都会覆盖该变量。即使将该变量设为静态类成员变量,它也会以相同的方式被覆盖。因此,与其在类的构造函数中分配全局变量,不如在 main() 中将其分配给 &eg1 将确保它不会被覆盖。【参考方案4】:没有。static
指针对象没有到类example
的内在链接,当然也没有到对象eg1
的内在链接。如果系统破坏 ptr
只是因为 eg1
超出范围,那么语言将非常损坏。
【讨论】:
以上是关于在 C++ 中删除其类的实例后,分配给 cpp 中定义的全局静态变量的内存是不是被释放?的主要内容,如果未能解决你的问题,请参考以下文章