相关文章推荐
坚强的鸵鸟  ·  使用 Gamepad API - Web ...·  1 月前    · 
坚强的煎鸡蛋  ·  Android ...·  1 年前    · 
热情的八宝粥  ·  关于CryptoJS ...·  1 年前    · 
踏实的韭菜  ·  深入解析 Cron ...·  1 年前    · 

前言:众所周知如果一个资源一旦读入就不需要修改,且多个线程都加载读取访问这个资源,那咱们就可以将这个资源声明为static类型,多线共享,既节省内存资源,也可以加快多线初始化这个资源的时间(一旦有一个线程对资源进行了加载,其他线程可以跳过加载资源的环节)

问题:简答描述下吧:  我的测试程序里, new了这样类的对象的指针,并加载了资源,进行了一系列的操作后,我delete掉这个指针,然后又去做别的操作,但是发现delete的操作并没有释放掉这个类对象加载的资源内存,导致了即使后面我的程序不用这个类了,但是内存还占着。

分析: 我们都知道C/C++中静态成员变量的内存的存放在全局内存的静态区域,即使是类内静态成员,也是放在全局内存中的。因此,我们虽然delete掉了这个类,但是并不代表我们真的释放掉了类内静态成员的内存,这些静态成员的内存会在整个进程退出的时候由系统回收,因此如果我们没有去显式的释放这些静态内存,而且没有像我问题中发现的那样,我们的程序貌似也跑的挺好。

但是这确实是一个问题。

解决方案:

这个时候有人说了,直接将静态改为非静态就好了,是的,改为非静态,内存回收的问题立即解决,都不用改调用程序。但是这种情况下,每个对象都会有个资源的副本,这就从另外一个角度浪费了内存(哈哈,拣了芝麻丢了西瓜),所以这种方案舍弃。

我试了两个其他解决方案:

本来我的类内的静态成员声明是这样的:

class A

private:

static  class B b;

方案1: 在A的析构里显式的调用B的析构函数,释放内存

A::~A()

b.~B();

方案2:将成员变量声明为指针,然后在A的构造里new,在A的析构里delete即可。

有错误的地方还希望指出,谢谢。

前言:总所周知如果一个资源一旦读入就不需要修改,且多个线程都加载读取访问这个资源,那咱们就可以将这个资源声明为static类型,多线共享,既节省内存资源,也可以加快多线初始化这个资源的时间(一旦有一个线程对资源进行了加载,其他线程可以跳过加载资源的环节)问题:简答描述下吧: 我的测试程序里, new了这样类的对象的指针,并加载了资源,进行了一系列的操作后,我delete掉这个指针,然后又去做别的操作,但是发现delete的操作并没有释放掉这个类对象加载的资源内存,导致了即使后面我的程序不用这个类了,..
【华为OD机试】免单统计(时间字符串排序—Java&Python& C++ &JS实现)华为商城举办了一个促销活动,如果某顾客是某一秒内最早时刻下单的顾客(可能是多个人),则可以获取免单。 请你编程计算有多少顾客可以获取免单。
下载时请看下面说明,对写一个动态的 内存 池很有帮助。 这是一个用 C++ 语言链表的方法实现的一个静态 内存 池代源码。原理就是先向系统申请一块大 内存 ,然后把这一大块分隔成相等的很多小块,然后在这这些小块的首地址部份放一个结构体,结构体中有一个值是用来标明这一小块是否使用中。在这里存放你要放存的数据就是用结构体首地址加结构体自身长度就得到要放数据的首地址了.具体看代码的实现吧。我说一下动态 内存 池的写法。那是我给公司写的就不能上传了。结构体和静态 内存 池的这个差不多一样,只是增加了一个成员用来记录每一节点到大块 内存 的首地址在到本节点的一个尺寸长度值,做法也是先申请一块大 内存 。我先从 释放 说起吧, 释放 本节点时看自己的相邻节点是不是有 释放 掉的,如果有则合并掉他们成为一个块,如果碰到相邻的节点是另外的一个大块的话就不用合并了,原因他和自己所在的这一个大块 内存 上物理地址不是连续,这里一定要记住, 释放 过程算法怎么去写就看你的了。下面是分配写法要考虑的。在分配一小块 内存 给高层使用时,如果是分配在尾节点去分配的情况,那好办啊,尾节点如果不够分配了就直接从系统去申请一块大 内存 ,节点连起来在分配,这里有可能会浪费掉一小块以结构体大小的一块 内存 ,如果够分配就直接分配了。如果是在中间节点去分配,这里就要将 释放 时合并的如果大于现在要分配的就拆开来用,如果拆开剩余的那一部份只有结构体大小就不用在拆开了。这些都是要考虑的东西,优化加快速度就看你自己了.可能看时不些不明白,看静态 内存 的写法后你就明白了.有时我也要下载其他人共享的东西,所以就一分吧.哈哈~~~~
和其它变量一样,指针是基本的变量,所不同的是指针包含一个实际的数据,该数据代表一个可以找到实际信息的 内存 地址。这是一个非常重要的概念。许多程序和思想依靠指针作为他们设计的基础。        怎样定义一个指针呢?除了你需要在变量的名称前面加一个星号外,其它的和别的变量定义一样。举个例子,以下代码定义了两个指针变量,它们都指向一个整数。 int* pNumberOne; int* pN
经常有这样的需求,在一个类里一些 成员变量 需要动态地分配 内存 ,以前是把这个成员声明为指针,然后在构造函数里指定为NULL类型,然后在析构函数里判断这个指针是否分配了 内存 ,如果分配了就进行删除。这种方式需要人工来做,工作量有点大,能否有更加高效的,能否有偷赖的方式呢?这是有的,如下的例子: #include <memory> class widget private: st...
C++ 无论何种数据,是否要 delete 关键看其空间是否使用new分配的。 1,函数冲定义的局部变量指针,单纯是一个局部变量是不用 delete ; 2, C++ 如果类中有一个指针数据成员,而没有用new, 析构函数也是不用 delete 的; 在类或函数中,int* ,char* 这些只要不是new的,也同样不用 释放 ,系统会自动把他们占的 内存 释放 掉,只有new的才会手动的去 delete int*,...
C++ 中的静态变量存储在静态存储区,也称为全局存储区。静态变量在程序开始执行时被初始化,直到程序结束时才被销毁。因此,静态变量的 内存 空间是在程序的整个生命周期中都被占用的,不会在函数调用结束时自动 释放 。 如果需要在程序运行时清除静态变量的 内存 ,可以使用 delete 运算符进行手动 释放 。但是,需要注意的是, delete 运算符只能用于在堆上分配的 内存 ,对于在静态存储区上分配的 内存 是无效的。 如果需要动态分配静态变量的 内存 ,并且在程序结束时 释放 这些 内存 ,可以考虑使用类似于单例模式的设计,通过 静态成员 函数来进行 内存 的分配和 释放 。例如: ```cpp class MyClass { public: static MyClass* getInstance() { static MyClass instance; return &instance; void doSomething() { // ... private: MyClass() { // constructor ~MyClass() { // destructor int main() { MyClass::getInstance()->doSomething(); // no need to manually release memory return 0; 在上面的代码中, 静态成员 函数 `getInstance` 返回一个静态的 `MyClass` 实例,该实例在第一次调用 `getInstance` 时被创建,并在程序结束时自动被销毁。这样,就可以在程序运行时动态分配静态变量的 内存 ,并在程序结束时自动 释放 这些 内存
static MyLog* mylog; // 将类的实例声明为类的私有静态成员,即单例 public: MyLog(){}; // 允许所有的构造函数,包括默认构造、赋值构造、拷贝构造 ~MyLog(); static MyLog* getInstance(); // 通过静态方法获得唯一的单例 MyLog* MyLog::mylog = nullptr; // 类的静态成员函数需要在类外定义才会被创建 MyLog::~MyLog(){ // 在析构函数中释放指针 std::cout<< "class delete begin.\n"; if(mylog!=nullptr){ delete mylog; std::cout<< "class delete end.\n"; MyLog* MyLog::getInstance(){ // new 出唯一的单例 if(mylog==nullptr){ mylog = new MyLog; return mylog; int main(){ MyLog a = {}; // 通过默认构造函数创建了一个对象 std::cout<< a.getInstance()<< std::endl; // 获得单例,并输出指针 // if(true){ // MyLog b(a); // 通过拷贝构造创建新对象 // std::cout<< b.getInstanc