栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【C语言】动态内存管理

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【C语言】动态内存管理

【C语言】动态内存管理 C语言 提供了一些用途较为特殊的函数,不像变量命名那样在定义之初将变量的空间固定,可以依照自己的需求,比较灵活的开辟空间,保证空间的利用效率;

首先介绍内存的简单概念:

\内存主要分为三大区域,用于存放不同类型的变量:
    栈区:存放临时的变量,例如局部变量,形参,也就是我们常用的开辟空间方法;
    静态区:存放静态变量 (static 定义),全局变量;
    堆区:使用动态内存开辟的主要区域;

C语言中参与动态内存分配的函数主要有: malloc calloc realloc free

malloc
void *malloc( size_t size );
//malloc 函数的含义是:在 堆区 申请了 size 个 字节 的空间,最后以 void* 的类型返回已申请空间的首地址;
//不会对申请的空间进行初始化;

一般在赋值过程将malloc开辟的空间转换成自己所需的指针类型,以便于维护。例如:

#include 
int* p = (int*)malloc(50);//向内存申请50个字节,用int*类型维护;

if( NULL == p)
    return;     
*p = 0; 

如果开辟失败,则会返回空指针 NULL

free

该函数主要是对向堆区申请的空间进行释放(将空间交还操作系统),其格式为:

void free( void *memblock );
// memblock是存放动态内存开辟的首地址的指针变量,函数无返回值

memblock存放的如果不是动态内存开辟的首地址(常规定义),free行为是未知的;

如果memblock存放的是NULL,free函数没有任何行为;

int* p = (int*)malloc(50);
free(p);                    //在使用free函数后,p指向的空间已被归还,但仍然指向首地址,
p = NULL;                   //所以在释放后一定要手动置空;
calloc
void *calloc( size_t num, size_t size );
//calloc 函数会在 堆区 上申请一块连续的 num 个大小为 size 的空间,并将此空间上的值置为0(malloc不初始化)
//返回申请空间的首地址;申请失败返回null;

其他使用方法与 malloc 相同

int* p = (int*) calloc(10, sizeof(int));
free(p);
p = NULL;   
if( NULL == p)
    printf("%sn",strerror(errno))   
realloc

该增容函数在动态内存开辟中最为灵活,是动态内存开辟函数的**“主力”**

在使用动态内存的过程中,可以用该函数改变所申请内存空间的大小,提高内存利用;

void *realloc( void *memblock, size_t size );

memblock 变量存放的是指向之前开辟好的空间的首地址;
realloc函数会将memblock指向空间的内容拷贝至新开辟的 大小为 size 个字节的空间中,并将此空间的首地址以 void* 类型的方式返回;

realloc 有两种开辟方法:

 1. 当memblock 指向开辟的空间后面有足够的未被使用的空间时,realloc会在此空间之后开辟空间,返回的地址与memblock存放的地址相等;
    2. 当memblock 指向开辟的空间后面没有有足够的未被使用的空间时,realloc会重新找一块空间,将memblock的数据拷贝过去,free掉memblock指向的空间,并将新的空间地址返回;
p = (int*)realloc(p, 30);


int* ptr = (int*)realloc(p, 40);
if( ptr != NULL)
   p = ptr;              

注意问题

  1. 动态空间的越界访问:如果需要增容空间,使用realloc,否则非法使用未开辟空间会造成未知错误;

  2. 非动态开辟的空间用free释放:常规定义的变量用free释放,程序会报错;

  3. 不能对存放已动态开辟的变量进行自加或自减操作,否则会导致使用free释放不完全,导致内存泄漏;

  4. 严禁对同一块空间进行过次free释放

  5. 动态内存开辟忘记释放(即内存泄漏):> 空间回收有两种方式:1. free释放 2. 程序结束退出,OS自动回收

    内存泄漏:在写有关动态内存开辟函数时,忘记使用完释放,导致程序运行过程中,即使该空间未被该程序使用,其他程序也无法使用这片空间,造成空间浪费;如果特定程序一直在开辟空间而不回收,会导致内存慢慢好干,没有空间可用,导致程序崩溃。

    void GetMemory(char* p)
    {
        p = (char*)malloc(100);            
        
    }
    void Test(void)
    {
        char* str = NULL;
        GetMemory(str);                
        strcpy(str, "hello world");
        printf(str)
    }
    

    局部性原理:在使用某些数据的时候,接下来使用的数据大概率会是周围的数据,在使用内存的数据时,也会将周围数据连同使用的数据加载到缓存中。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/311696.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号