在 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 &amp;eg1 声明既是危险的错误,也是完全没有必要的...... 【参考方案1】:

首先,如果你运行你发布的代码,你会得到以下结果:

malloc: *** error for object 0x7fff560a8830: pointer being freed was not allocated

这是因为您删除了&amp;eg1,而没有先使用new 在堆上为其分配内存。

其次,析构函数/delete 只会清理与example 对象关联的内存。它没有义务清理static example* ptr

从另一个角度来看,析构函数和delete 旨在清理动态分配的数据,即存在于堆上的数据,而不仅仅是当前函数调用的堆栈上。相比之下,static example* ptr 是一个全局变量,它存在于全局数据段上,与堆和堆栈分开。

因此,您可以看到deleteexample 对象的析构函数不会释放分配用于存储指针本身的内存,因为它们都没有权限这样做。

编辑 ------------------

正如其他人所说,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 中定义的全局静态变量的内存是不是被释放?的主要内容,如果未能解决你的问题,请参考以下文章

在C++的class类中,要分配一块大的内存,该如何操作?

c++基类包含派生类的实例

返回在堆上分配的类的实例(C++)[关闭]

在 cpp 中重新定义 new 和 delete 运算符以跟踪内存分配:无法跟踪整个内存块的删除大小

C++ 模板类的实现为何放在.h中

当指针指向的对象被另一个类的实例删除时重新分配指针