精华内容
下载资源
问答
  • c语言中动态内存申请与释放的简单理解 在C里内存管理是通过专门的函数来实现的与c++不同在c++中是通过newdelete函数动态申请释放内存的 1分配内存 malloc 函数 需要包含头文件 #include <alloc.h> 或 #include ...
  • C语言内存池算法MTK任务内存申请和释放C语言内存池算法MTK任务内存申请和释放C语言内存池算法MTK任务内存申请和释放C语言内存池算法MTK任务内存申请和释放C语言内存池算法MTK任务内存申请和释放
  • 关于QT的内存申请和释放

    千次阅读 2017-11-03 14:47:46
    关于QT的内存申请和释放 进入QT gui 设计的学习也有大半年年了,在做关于QT项目时遇到过关于内存释放错误的问题,曾经一度纠结过!以下是个人关于qt内存管理机制的总结:   首先看一个类:  为了简单...

    关于QT的内存申请和释放

    进入QT gui 设计的学习也有大半年年了,在做关于QT项目时遇到过关于内存释放错误的问题,曾经一度纠结过!以下是个人关于qt内存管理机制的总结:

     

    首先看一个类:

           为了简单起见,我不完成任何功能,只做一个构造函数和一个析构函数。

     

    代码 1.

    class MyDialog : public QDialog

    {

           Q_OBJECT

    public:

           MyDialog();

           ~MyDialog();

    private:

           QHBoxLayout *hLayout;

           QVBoxLayout *vLayout ;

           QPushButton *btn;

           QLineEdit *lineEdit ;

    };

     

    代码2.

     

    MyDialog::MyDialog()

           :QDialog()

    {

           btn = new QPushButton("Hello");

           lineEdit = new QLineEdit;

           hLayout = new QHBoxLayout;

           vLayout = new QVBoxLayout ;

          

           hLayout->addWidget(lineEdit);

           hLayout->addWidget(btn);

          

           vLayout->addLayout(hLayout1);

           setLayout(vLayout) ;

           connect(btn,SIGNAL(clicked()),this,SLOT(close()));

    }

     

    MyDialog::~MyDialog()

    {

          

           delete btn ;

           delete lineEdit;

    delete hLayout;

           delete vLayout ;

    }

     

    代码3.

     

    int main(int argc , char ** argv)

    {

           QApplication app (argc ,argv) ;

          

           MyDialog dlg ;

           dlg.show();

           return app.exec();

    }

    代码分析:

           从类的声明中,就不难看出,hLayout vLayout btn lineEdit;都是堆结构,就需要我没在 .cpp中实例化一下。

     

           从类的实现部分中,可以看出,好hLayout 布局是放在vLayout中的,按钮和编辑框是放在和Layout中的。

     

           现在看一下析构函数。

           经过C语言的学习我们知道,申请的堆空间如果不主动释放,系统不会帮你释放的,所以有new 就要有delete 

           析构函数中,先释放按钮和标签 gui组件,然后释放不可见组件(布局),现在注意了,我们应该先释放好hLayout ,然后在释放Vlayout

           因为hLayout是建立在vLayout上的,如果释放了hLayout 的话,hLayout首先会与vLayout解除关系!

           如果在释放的时候,hLayout  vLayout 的释放顺序颠倒过来,就会出现段错误,因为先 delete vLayout,在delete hLayout 的时候,hLayout 将会与vLayout解除关系,但是此时vLayout已经不存在了,所以就会产生段错误。

     

           你些许会有疑问,那为什么btn  lineEdit delete的先后顺序可以顺便呢。

     

    这是因为 btn  lineEdit 都是可见的Gui组件,delete gui组件时,不需要解除他与布局类的关系。所以顺序就可以随便写了。

     

    总结:

           在使用堆结构定义对象的时候,特别是不可见组件,一定要从下往上释放(我说的是相对栈结构),也就是如果,layout1 包含layout2layout2 包含layout3 ,应该先delete layout3,在layout2,最后layout1 。这样就不容易出错了。

     

    以上说的都是堆结构的,接下来总结一点,关于堆栈混用的。

    现在看下面的类:

    class MyDialog : public QDialog

    {

           Q_OBJECT

    public:

           MyDialog();

           ~MyDialog();

    private:

           QHBoxLayout hLayout;

           QVBoxLayout vLayout ;

           QPushButton *btn;

           QLineEdit *lineEdit ;

    };

    这里我只是把 hLayout  vlayout的结构改成了栈结构,而btn  lineEdit还是原来的堆结构,构造函数在此就不写出了,逻辑和上面是一样的还是hLayout 放在vlayout中的。

    下面是析构函数:

     

    MyDialog::~MyDialog()

    {

           delete btn ;

           delete lineEdit;

    }

     

    运行一下代码将会发现,出现了

    *** glibc detected *** ./shiyan: double free or corruption (out): 0xbfa0a800 ***

    ======= Backtrace: =========

    /lib/libc.so.6[0xc4bac1]

    /lib/libc.so.6(cfree+0x90)[0xc4f0f0]

    /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0x59d96f1]

    /usr/lib/libstdc++.so.6(_ZdaPv+0x1d)[0x59d974d]

    ./shiyan(__gxx_personality_v0+0x357)[0x804a1e3]

    ./shiyan(__gxx_personality_v0+0x269)[0x804a0f5]

    /lib/libc.so.6(__libc_start_main+0xe0)[0xbf8390]

    ./shiyan(_ZNK7QDialog8sizeHintEv+0x55)[0x8049fd1]

    ======= Memory map: ========

    00110000-00111000 r-xp 00110000 00:00 0          [vdso]

    00111000-009c5000 r-xp 00000000 fd:00 3441508    /root/qt/lib/libQtGui.so.4.4.0

    009c5000-009e9000 rwxp 008b4000 fd:00 3441508    /root/qt/lib/libQtGui.so.4.4.0

    009e9000-009ea000 rwxp 009e9000 00:00 0

    009ea000-009ee000 r-xp 00000000 fd:00 1412324    /lib/libgthread-2.0.so.0.1400.2

    009ee000-009ef000 rwxp 00003000 fd:00 1412324    /lib/libgthread-2.0.so.0.1400.2

    009ef000-009f6000 r-xp 00000000 fd:00 1412323    /lib/librt-2.7.so

     

    乱七八糟的东西,这是为什么呢?

    这是因为,栈结构会被系统自动回收,在系统自动释放hLayoutLayout的时候,会把 btnlineEdit也释放掉,然后自己在写delete btndelete lineEdit的时候就会出现 double free,因为了把栈结构也释放掉了。

    展开全文
  • Unity内存申请和释放

    万次阅读 2014-10-28 15:06:41
    Unity内存申请和释放 发表于 Unity 2014-07-01 15:01 字数: 2396 阅读量: 43 1.资源类型 GameObject, Transform, Mesh, Texture, Material, Shader, Script各种其他Assets。 2.资源创建方式...

    转载自http://www.jianshu.com/p/b37ee8cea04c

    Unity内存申请和释放

    1.资源类型

    GameObject, Transform, Mesh, Texture, Material, Shader, Script和各种其他Assets。

    2.资源创建方式

    • 静态引用,在脚本中加一个public GameObject变量,在Inspector面板中拖一个prefab到该变量上,然后在需要引用的地方Instantiate;
    • Resource.Load,资源需要放在Assets/Resources目录下;
    • AssetBundle.Load, Load之后Instantiate。

      3. 资源销毁方式

    • GameObject.Destroy(gameObject),销毁该物体;
    • AssetBundle.Unload(false),释放AssetBundle文件内存镜像,不销毁Load创建的Assets对象;
    • AssetBundle.Unload(true),释放AssetBundle文件内存镜像同时销毁所有已经Load的Assets内存镜像;
    • Resources.UnloadAsset(Object),释放已加载的Asset对象;
    • Resources.UnloadUnusedAssets,释放所有没有引用的Asset对象。

      4. 生命周期

      实验篇

      实验中创建了一个简单场景,场景中创建了一个Empty GameObject,上面挂了一个脚本,在Awake函数中通过协程函数来创建资源,具体的Coroutine函数下面都有。
      实验中创建的Prefab是一个坦克车,加入场景中场景内存增加3M左右,同时创建了一个AssetBundle资源供AssetBundle使用。

      1. Resources.Load方式加载一个Prefab, 然后Instantiate GameObject

      代码如下:
       IEnumerator LoadResources()
        {
            // 清除干净以免影响测试结果
            Resources.UnloadUnusedAssets();
            // 等待5秒以看到效果
            yield return new WaitForSeconds(5.0f);
    
            // 通过Resources.Load加载一个资源
            GameObject tank = Resources.Load("Role/Tank") as GameObject;
            yield return new WaitForSeconds(0.5f);
    
            // Instantiate一个资源出来
            GameObject tankInst = GameObject.Instantiate(tank, Vector3.zero, Quaternion.identity) as GameObject;
            yield return new WaitForSeconds(0.5f);
    
            // Destroy一个资源
            GameObject.Destroy(tankInst);
            yield return new WaitForSeconds(0.5f);
    
            //释放无用资源
            tank = null;
            Resources.UnloadUnusedAssets();
    
            yield return new WaitForSeconds(0.5f);
        }

    执行结果如下:
    图片1.png

    下面是统计结果:

    数据描述 Memory Texture Mesh Material GameObjects Objects in Scene Total Objects
    初始 72.8M 1271/8.0M 35/223.0K 25/10.2K 7 211 2187
    Resources.Load 72.8M 1271/8.0M 36/0.8M 25/10.2K 7 211 2280
    Instantiate 75.3M 1272/9.3M 36/0.8M 26/10.7K 52 303 2375
    Destroy 74.7M 1272/9.3M 36/0.8M 26/10.7K 7 211 2283
    Resources.UnloadUnusedAssets 72.3M 1271/8.0M 35/223.0K 25/10.2K 7 211 2187

    从这里我们得出如下结论:

    • Resouces.Load一个Prefab相对于Instantiate一个资源来说是相对轻量的一个操作,上述过程中,Resources.Load加载一个Prefab几乎没有消耗内存,而Instantiate消耗了2.5M的资源空间。Resources.Load增加了Mesh和Total Object的数量,而Instantiate增加了GameObjects,Objects In Scene和Total Objects的数量;
    • Destroy一个GameObject之后,内存有所减少,但是比较少,本例中减少了0.6M;Instantiate和Destroy前后Material和Texture没有还原,用以后面继续进行Instantiate之用。

    若没有调用Resources.UnloadUnusedAssets,则结果如下:

    图片2.png

    统计结果如下:

    数据描述 Memory Texture Mesh Material GameObjects Objects in Scene Total Objects
    初始 58.9M 1258/7.5M 34/219.2K 22/9.0K 7 117 2078
    Resources.Load 60.0M 1258/7.5M 35/0.8M 22/9.0K 7 117 2171
    Instantiate 62.5M 1259/8.9M 36/0.8M 23/9.5K 52 209 2256
    Destroy 61.8M 1259/8.9M 35/0.8M 23/9.5K 7 117 2174

    得出如下结论:
    如果不手动执行Resources.UnloadUnusedAssets,则多余的Mesh,Material和Object不会主动释放。

    2. 以AssetBundle.Load的方式加载一个Prefab,然后Instantiate一个GameObject

    代码如下:

     IEnumerator LoadAssets(string path)
        {
            // 清除干净以免影响测试结果
            Resources.UnloadUnusedAssets();
    
            // 等待5秒以看到效果
            yield return new WaitForSeconds(5.0f);
    
            // 创建一个WWW类
            WWW bundle = new WWW(path);
            yield return bundle;
            yield return new WaitForSeconds(0.5f);
    
            // AssetBundle.Load一个资源
            Object  obj =  bundle.assetBundle.Load("tank");
            yield return new WaitForSeconds(0.5f);
    
            // Instantiate一个资源出来
            GameObject tankInst = Instantiate(obj) as GameObject;
            yield return new WaitForSeconds(0.5f);
    
            // Destroy一个资源
            GameObject.Destroy(tankInst);
            yield return new WaitForSeconds(0.5f);
    
            // Unload Resources
            bundle.assetBundle.Unload(false);
            yield return new WaitForSeconds(0.5f);
    
            // 释放无用资源
            //obj = null;
            //Resources.UnloadUnusedAssets();
    
            yield return new WaitForSeconds(0.5f);
        }

    执行结果如下:
    图片3.png

    统计结果如下:

    数据描述 Memory Texture Mesh Material GameObjects Objects in Scene Total Objects
    初始 59.9M 1267/7.8M 35/223.0K 25/10.2K 7 127 2099
    new WWW 62.0M 1267/7.8M 35/223.0K 25/10.2K 7 127 2099
    AssetBundle.Load 64.5M 1268/9.2M 36/0.8M 26/10.5K 7 127 2196
    Instantiate 65.6M 1268/9.2M 36/0.8M 26/10.7K 52 219 2288
    Destroy 63.9M 1268/9.2M 36/0.8M 26/10.7K 7 127 2196
    AssetBundle.Unload 63.7M 1268/9.2M 36/0.8M 26/10.7K 7 127 2196
    Resources.UnloadUnusedAssets 61.8M 1267/7.8M 35/223.0K 25/10.2K 7 127 2099

    得出如下结论:
    通过WWW Load AssetBundle的方式加载一个资源时会自动加载相应的Mesh,Texture和Material,而通过Resouces.Load方式进行加载只会加载Mesh信息。因此通过AssetBundle方式加载后Instantiate一个资源的内存消耗较小,本例中AssetBundle.Load增加了2.5M的内存,而Instantiate增加了1.1M的内存。相比较Resources.Load后Instantiate的内存增量要小很多。

    3. 通过静态绑定的方法来Instantiate一个资源

    代码如下:

        IEnumerator InstResources()
        {
            Resources.UnloadUnusedAssets();
            yield return new WaitForSeconds(5.0f);
    
            GameObject inst = GameObject.Instantiate(tank, Vector3.zero, Quaternion.identity) as GameObject;
            yield return new WaitForSeconds(1f);
    
            GameObject.Destroy(inst);
            yield return new WaitForSeconds(1f);
    
            //释放无用资源
            tank = null;
            Resources.UnloadUnusedAssets();
    
            yield return new WaitForSeconds(1f);
        }

    执行结果如下:
    图片4.png

    统计结果如下:

    数据描述 Memory Texture Mesh Material GameObjects Objects in Scene Total Objects
    初始 62.0M 1268/7.9M 36/0.8M 25/10.2K 7 134 2202
    Instantiate 64.4M 1269/9.2M 36/0.8M 26/10.7K 8 137 2207
    Destroy 64.0M 1269/9.2M 36/0.8M 26/10.7K 7 134 2204
    UnloadUnused Resources 62.3M 1268/7.9M 35/226.3K 25/10.2K 7 134 2107

    得出结论如下:
    通过静态绑定的方式各种资源的加载顺序和Resources.Load的方式是一样的,一个GameObject创建时,其Component中静态绑定的GameObject只会加载Mesh信息,只有当该GameObject Instantiate出来之后才会加载Texture和Material信息。

    理论篇

    加载资源的过程可以分为两个阶段,第一阶段是使用Resources.Load或者AssetBundle.Load加载各种资源,第二阶段是使用GameObject.Instantiate克隆出一个新的GameObject。
    Load的资源类型包括GameObject, Transform, Mesh, Texture, Material, Shader和Script等各种资源,但是Resources.Load和AssetBundle.Load是有区别的。
    使用Resources.Load的时候在第一次Instantiate之前,相应的Asset对象还没有被创建,直到第一次Instantiate时才会真正去读取文件创建这些Assets。它的目的是实现一种OnDemand的使用方式,到该资源真正使用时才会去创建这些资源。
    而使用AssetBundle.Load方法时,会直接将资源文件读取出来创建这些Assets,因此第一次Instantiate的代价会相对较小。
    上述区别可以帮助我们解释为什么发射第一发子弹时有明显的卡顿现象的出现。

    然后我们再来了解一下Instantiate的过程。Instantiate的过程是一个对Assets进行Clone(复制)和引用相结合的过程,Clone的过程需要申请内存存放自己的数据,而引用的过程只需要直接一个简单的指针指向一个已经Load的资源即可。例如Transform是通过Clone出来的,Texture和TerrainData是通过引用复制的,而Mesh,Material,PhysicalMaterial和Script是Clone和引用同时存在的。以Script为例,Script分为代码段和数据段,所有需要使用该Script的GameObject使用的代码是一样的,而大家的数据有所区别,因此对数据段需要使用Clone的方式,而对代码段需要使用引用的方式来复制。
    因此Load操作其实Load一些数据源出来,用于创建新对象时被Clone或者被引用。

    然后是销毁资源的过程。当Destory一个GameObject或者其他实例时,只是释放实例中那些Clone出来的Assets,而并不会释放那些引用的Assets,因为Destroy不知道是否有其他人在引用这些Assets。等到场景中没有任何物体引用到这些Assets之后,它们就会成为UnusedAssets,此时可以通过Resources.UnloadUnusedAssets来进行释放。AssetBundle.Unload(false)不行,因为它只会释放文件的内存镜像,不会释放资源;AssetBunde.Unload(true)也不行,因为它是暴力的释放,可能有其他对象在引用其中的Assets,暴力释放可能导致程序错误。
    另外需要注意,系统在加载新场景时,所有的内存对象都会被自动销毁,这包括了Resources.Load加载的Assets, 静态绑定的Assets,AssetBundle.Load加载的资源和Instantiate实例化的对象。但是AssetBundle.Load本身的文件内存镜像(用于创建各种Asset)不会被自动销毁,这个必须使用AssetBundle.Unload(false)来进行主动销毁。推荐的做法是在加载完资源后立马调用AssetBunble.Unload(false)销毁文件内存镜像。
    下图可以帮助理解内存中的Asset和GameObject的关系。
    图片5.jpg

    总结篇

    • 为了不出现首次Instantiate时卡顿的现象,推荐使用AssetBundle.Load的方式代替Resources.Load的方式来加载资源;
    • 加载完资源后立马调用AssetBunble.Unload(false)释放文件内存镜像;
    • Unity自身没有提供良好的内存申请和释放管理机制,Destroy一个GameObject会马上释放内存而不是进行内部的缓存,因此应用程序对频繁不用的对象如NPC,FX等进行对象池管理是必要的,减少内存申请次数;
    • 何时进行Resources.UnloadUnusedAssets是需要讨论的一个问题。

    Ref:

    http://game.ceeger.com/forum/read.php?tid=4394
    http://game.ceeger.com/forum/read.php?tid=4466

    展开全文
  • 一个简单带日志的内存申请和释放的类(LogMemory)。 LogMemory主要有如下功能: 1)申请释放内存,并且带有日志输出。其中日志使用了log4cplus。 2)申请释放2维和3维的数组。
  • C++ 二维指针的内存申请和释放

    千次阅读 2019-05-23 09:52:56
    //=======以二维int型数组为例========= cin >> m >> n; // m,n分别为行数列数 int ** p; p = new int*[m]; //以一个指针的指针指向一个指针数组 for (int i = 0; i <...
    //=======以二维int型数组为例=========
     
    cin >> m >> n;                              // m,n分别为行数和列数
     
    int ** p;
    p = new int*[m];                           //以一个指针的指针指向一个指针数组
    for (int i = 0; i < m; i++)
    	p[i] = new int[n];                     //给指针数组里的每个指针申请一维空间
     
    然后就可以如二维数组给p[i][j]赋值了.
     
    最后别忘了释放 :
     
    for (int i = 0; i < m; i++)
    	delete[]p[i];
    delete[]p;

     

    展开全文
  • 动态内存申请和释放

    千次阅读 2019-01-20 22:15:18
    动态内存申请和释放 文章目录动态内存申请和释放1. malloc() free() 的基本概念以及基本用法1.1 函数原型及说明:1.2 被释放的指针1.3 注意事项2. malloc() 到底从哪里得来了内存空间2.1 堆介绍2.2 栈介绍2.3...

    动态内存的申请和释放

    1. malloc() 和 free() 的基本概念以及基本用法

    1.1 函数原型及说明:

    void *malloc(long NumBytes)

    该函数分配了 NumBytes 个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。

    关于分配失败的原因,应该有多种,比如说空间不足就是一种。

    void free(void *FirstByte)

    该函数是将之前用 malloc 分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由,可以被分配给其他函数(进程)。

    1.2 被释放的指针

    char *p = (char *)malloc(100 * sizeof(char));

    当动态内存不再使用,就要将其所指向的空间释放掉,delete 和 free 函数一样,不修改它参数对应指针指向的内容,也不修改指针本身,只是在堆内存管理结构中 将指针指向的内容标记为可被重新分配 。就是告诉系统这个地址的内存我已经不用了,系统可以重新分配给别的程序了,这个地址p的值当然不会变,它只有在生存期结束后才会被释放。

    1.3 注意事项

    • 申请了内存空间后,必须检查 是否分配成功

    • 当不需要再使用申请的内存时,记得释放;释放后应该把指向这块内存的指针指向 NULL ,防止程序后面不小心使用了它。

    • 这两个函数应该是配对。如果申请后不释放就是 内存泄露 (内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果);如果无故释放那就是什么也没有做。释放只能一次,如果释放两次及两次以上会出现错误(释放空指针例外,释放空指针其实也等于啥也没做,所以释放空指针释放多少次都没有问题)。

    • 虽然malloc()函数的类型是 (void *),任何类型的指针都可以转换成 (void *),但是最好还是在前面进行强制类型转换,因为这样可以躲过一些编译器的检查。

    2. malloc() 到底从哪里得来了内存空间

    malloc() 到底从哪里得到了内存空间?

    答案是从 里面获得空间。也就是说函数返回的指针是指向堆里面的一块内存。操作系统中有 一个记录空闲内存地址的链表 。当操作系统收到程序的申请时,就会遍历该链表,然后就寻找第一个空间大于所申请空间的堆结点,然后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。就是这样!

    2.1 堆介绍

    堆是大家共有的空间,分全局堆局部堆全局堆就是所有没有分配的空间,局部堆就是用户分配的空间。堆在操作系统对进程 初始化的时候分配,运行过程中也可以向系统要额外的堆,但是记得用完了要还给操作系统,要不然就是内存泄漏。

    说到堆必然会想到栈。

    2.2 栈介绍

    栈是线程独有的,保存其运行状态和局部自动变量的。栈在线程开始的时候初始化,每个线程的栈互相独立。栈被用来在函数之间传递参数。操作系统在切换线程的时候会自动的切换栈,就是切换 SS/ESP 寄存器。栈空间不需要在高级语言里面显式的分配和释放。

    2.3 栈空间和堆空间的使用方式

    栈是由编译器自动分配释放,存放函数的参数值、局部变量的值等。操作方式类似于数据结构中的栈。

    堆一般由程序员分配释放,若不释放,程序结束时可能由OS回收。注意这里说是可能,并非一定。所以我想再强调一次,记得要释放!

    注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

    所以,举个例子,如果你在函数上面定义了一个指针变量,然后在这个函数里申请了一块内存让指针指向它。实际上,**这个指针的地址是在栈上,但是它所指向的内容却是在堆上面的!**这一点要注意!所以,再想想,在一个函数里申请了空间后,比如说下面这个函数:

    void Function(void)
    {
       char *p = (char *)malloc(100 * sizeof(char));
    }
    

    就这个例子,千万不要认为函数返回,函数所在的栈被销毁指针也跟着销毁,申请的内存也就一样跟着销毁了!这绝对是错误的!因为申请的内存在堆上,而函数所在的栈被销毁跟堆完全没有啥关系。所以,还是那句话:记得释放!

    free() 释放的是指针指向的内存!注意!释放的是内存,不是指针。

    3. malloc() 以及 free() 的机制详解

    事实上,仔细看一下free()的函数原型,也许也会发现似乎很神奇,free() 函数非常简单,只有一个参数,只要把指向申请空间的指针传递给 free() 中的参数就可以完成释放工作!为什么不需要我们输入申请的空间大小呢?

    这里要追踪到 malloc() 的申请问题了。申请的时候实际上占用的内存要比申请的大。因为超出的空间是用来记录对这块内存的管理信息。先看一下在《UNIX环境高级编程》中第七章的一段话:

    大多数实现所分配的存储空间比所要求的要稍大一些,额外的空间用来记录管理信息——分配块的长度,指向下一个分配块的指针等等。这就意味着如果写过一个已分配区的尾端,则会改写后一块的管理信息。这种类型的错误是灾难性的,但是因为这种错误不会很快就暴露出来,所以也就很难发现。将指向分配块的指针向后移动也可能会改写本块的管理信息。

    以上这段话已经给了我们一些信息了。malloc() 申请的空间实际分配了两个空间。一个就是用来记录管理信息的空间,另外一个就是用户想要的空间。而用来记录管理信息的实际上是一个结构体。在 C 语言中,用结构体来记录同一个对象的不同信息是天经地义的事!下面看看这个结构体的原型:

    struct mem_control_block 
    {
        int is_available;    //这是一个标记
        int size;            //这是实际空间的大小
    };
    
    void free(void *ptr) 
    {
         struct mem_control_block *free;
         free = ptr - sizeof(struct mem_control_block);
         free->is_available = 1;
         return;
    }
    

    看一下函数第二句,这句非常重要和关键。其实这句就是把指向可用空间的指针倒回去,让它指向管理信息的那块空间,因为这里是在值上减去了一个结构体的大小! 然后将is_available的值置为1,表明被释放。

    展开全文
  • 动态内存:malloc函数: 作用:用于申请一块连续的指定大小的内存块区域以(void *)类型返回分配的内存区域地址,当无法知道内存具体位置的时候,就要用到动态分配内存。函数声明:(返回为(void *)类型)void *...
  • 内存申请和释放及堆连续

    千次阅读 2016-12-21 22:54:10
    C语言有两种内存申请方式: 1、静态申请:当你声明全局或静态变量的时候,会用到静态申请内存。静态申请的内存有固定的空间大小。空间只在程序开始的时候申请一次,并且不再释放(除非程序结束)。 2、自动...
  • sk_buff 内存申请和释放

    千次阅读 2017-01-08 16:05:54
     内核对于sk_buff结构的内存分配不是一般的结构动态内存申请一样:只分配指定大小的内存空间。而是在开始的时候,在初始化函数skb_init()中就分配了两段内存(skbuff_head_cacheskbuff_fclone_cache )来供sk_...
  • 科目:操作系统原理课程设计 题目:内存申请释放 内容:有完整的可以运行的c语言编写的程序源码。
  • 一 数组指针的空间释放 1 2 3 4 int (*p)[3] = new int [4][3]; // ... delete []p; //---1 delete[](*p);  ...在释放这个二维数组时,应该使用12哪种方式呢?哪种对呢?
  • 申请和释放某一个类型的内存方法:int *p = new int; delete p;申请块内存的方法int *arr = new int[10]; delete []arr;判断内存是否申请成功int *p =new int [100000]; if(NULL == p) ... cout内存申请失败"; }
  • 申请释放都差不多,那么它们之间到底是否有差别呢? C 语言的malloc() free() 并不会调用析构函数构造函数。C++的 new delete 操作符 是 “类意识” ,并且当调用new的时候会调用类的构造函数当delete ...
  • 本例中使用stm32c8t6 mdk3.5  gcc-arm-none-eabi-4_9。使用EmBitz IDE ARM GCC Compiler。 单片机是不建议使用 内存管理函数,但是在物联网应用当中,内存资源很是宝贵,MQTT 协议需要SSL TLS,数据签名 MD5,...
  • C语言中,函数参数或者返回值中如果包含指针指向动态分配的内存区域,那么管理申请和释放就显得十分麻烦,一不小心就容易出错,今天突发奇想借鉴高级语言函数式编程的思想,其实C语言里的函数指针已经非常完美了,...
  • 主函数需要调用一个dll库函数并返回一块大小不定的存储着处理结果的内存,这时容易想到两种选择:一是使用vector的引用作为形参,二是使用指针,在主函数中定义指针,而在dll库函数中申请内存
  • 模拟内存申请释放

    2014-04-06 17:15:00
    java中用可变长数组模拟内存申请释放
  • C/C++申请和释放内存

    万次阅读 多人点赞 2018-01-11 11:39:47
    new delete 是 C++ 用于管理堆内存的两个运算符,对应于C语言中的 malloc free,但是 malloc free 是函数,而new delete 是运算符。除此之外,new 在申请内存的同时,还会调用对象的构造函数,而 malloc...
  • C 内存申请和释放

    千次阅读 2012-03-15 23:21:30
    C语言跟内存申请相关的函数主要有 alloca,calloc,malloc,free,realloc,sbrk等. 其中alloca是向栈申请内存,因此无需释放. malloc分配的内存是位于堆中的,并且没有初始化内存的内容,因此基本上malloc之后,调用...
  • C语言中指针动态内存申请和释放

    千次阅读 2020-08-20 21:10:28
    什么是动态内存申请和释放? 当程序运行到需要一个动态变量时,需要向系统的堆中申请一块内存,用来存储这块变量,这就是内存申请。当程序不需要这个变量时,就需要把申请的这块内存释放掉,这就是内存释放...
  • DELPHI内存详解(7)-内存申请和释放

    千次阅读 2011-09-16 11:46:16
    DELPHI内存详解(7)-内存申请和释放 2010-06-04 16:41 1 内存分配常见函数 GetMemFreeMem、GetMemoryFreeMemory、NewDispose、StrAllocStrDispose、AllocMem、
  • C语言中动态内存申请和释放

    千次阅读 2019-03-16 12:15:47
    什么是动态内存申请和释放? 当程序运行到需要一个动态分配的变量时,必须向系统申请取得堆中的一块所需大小的存储空间,用于存储该变量。当不再使用该变量时,也就是它的生命结束时,要显式释放它所占用的存储...
  • 内核对于sk_buff结构的内存分配不是一般的结构动态内存申请一样:只分配指定大小的内存空间。而是在开始的时候,在初始化函数skb_init()中就分配了两段内存(skbuff_head_cacheskbuff_fclone_cache )来供sk_...
  • 申请内存空间和释放内存空间

    千次阅读 2016-10-12 22:02:05
    1、申请内存空间 2、释放内存空间
  • 任意字节对齐的内存分配和释放。 源码实现 // 实现任意字节对齐的内存分配和释放 void *AllignedMalloc(size_t size, int aligned) { // aligned is a power of 2 assert((aligned&(aligned - 1)) == 0); // ...
  • c++内存的动态申请释放 内存管理永远都是c++程序员应该关心的事
  • 关于动态内存申请和释放

    千次阅读 2017-01-10 18:06:37
    关于malloc(p)free(p): malloc主要用来分配内存空间,通常是结合指针进行使用,通常是在声明了一个指针之后, 为该指针所指向的数据分配一个内存空间,不然该指针就成为野指针了。如下: int *p ; ...
  • 模拟内存申请释放的程序范例,在linux平台下分文件写的,供大家借鉴,熟悉c数据结构

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 208,627
精华内容 83,450
关键字:

内存的申请和释放