千家信息网

C语言动态内存分配怎么使用

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章主要介绍了C语言动态内存分配怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C语言动态内存分配怎么使用文章都会有所收获,下面我们一起来看看吧。一、动态内存分
千家信息网最后更新 2026年11月01日C语言动态内存分配怎么使用

这篇文章主要介绍了C语言动态内存分配怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C语言动态内存分配怎么使用文章都会有所收获,下面我们一起来看看吧。

一、动态内存分配的意义

C语言中的一切操作都是基于内存的

变量和数组都是内存的别名

  • 内存分配由编译器在编译期间决定

  • 定义数组的时候必须指定数组长度

  • 数组长度是在编译期就必须确定的

需求:程序运行的过程中,可能需要使用一些额外的内存空间

二、malloc 和 free

malloc 和 free 用于执行动态内存分配和释放

  • malloc 所分配的是一块连续的内存

  • malloc 以字节为单位,并且不带任何的类型信息

  • free 用于将动态内存归还系统

void* malloc(size_t size);

void free(void* pointer);

注意事项

  • malloc 和 free 是库函数,而不是系统调用

  • malloc 实际分配的内存可能会比请求的多

  • 不能依赖于不同平台下的 malloc 行为

  • 当请求的动态内存无法满足时 malloc 返回 NULL

  • 当 free 的参数为 NULL 时,函数直接返回

下面看一个内存泄漏检测模块的示例:

test.c:

#include #include "mleak.h" void f() {    MALLOC(100);} int main(){    int* p = (int*)MALLOC(3 * sizeof(int));     f();     p[0] = 1;    p[1] = 2;    p[2] = 3;         FREE(p);         PRINT_LEAK_INFO();        return 0; }

mleak.h:

#ifndef _MLEAK_H_ #define _MLEAK_H_ #include  #define MALLOC(n) mallocEx(n, __FILE__, __LINE__) #define FREE(p) freeEx(p)  void* mallocEx(size_t n, const char* file, const line); void freeEx(void* p); void PRINT_LEAK_INFO(); #endif

mleak.c:

#include "mleak.h" #define SIZE 256  /* 动态内存申请参数结构体 */ typedef struct{    void* pointer;    int size;    const char* file;    int line; } MItem; static MItem g_record[SIZE]; /* 记录动态内存申请的操作 */ void* mallocEx(size_t n, const char* file, const line){    void* ret = malloc(n); /* 动态内存申请 */        if( ret != NULL )    {        int i = 0;                /* 遍历全局数组,记录此次操作 */         for(i = 0; i < SIZE; i++)        {             /* 查找位置 */             if( g_record[i].pointer == NULL )            {                g_record[i].pointer = ret;                g_record[i].size = n;                g_record[i].file = file;                g_record[i].line = line;                break;             }         }     }        return ret; } void freeEx(void* p){    if( p != NULL )    {        int i = 0;                 /* 遍历全局数组,释放内存空间,并清除操作记录 */         for(i = 0; i < SIZE; i++)        {            if( g_record[i].pointer == p )             {                 g_record[i].pointer = NULL;                 g_record[i].size = 0;                 g_record[i].file = NULL;                 g_record[i].line = 0;                                 free(p);                                 break;             }         }     } } void PRINT_LEAK_INFO(){     int i = 0;        printf("Potential Memory Leak Info:\n");         /* 遍历全局数组,打印未释放的空间记录 */     for(i = 0; i < SIZE; i++)    {        if( g_record[i].pointer != NULL )        {            printf("Address: %p, size:%d, Location: %s:%d\n", g_record[i].pointer, g_record[i].size, g_record[i].file, g_record[i].line);        }    } }

输出结果如下, 因为 MALLOC(100); 之后没有进行释放内存,所以被检查出来了。

暂时不能用于工程开发,需要再开发才行。因为 malloc 往往在不同的线程中被调用,因此 malloc 函数必须要有互斥的操作。因为 static MItem g_record[SIZE]; 这个静态全局数组是一种临界区,必须被保护起来。

三、关于 malloc(0)

malloc(0); 将返回什么?

下面看一段代码:

#include #include  int main(){    int* p = (int*) malloc(0);        printf("p = %p\n", p);        free(p);     return 0;}

输出结果如下:

这说明 malloc(0) 是合法的,内存地址其实包含两个概念,一个是内存的起始地址,一个是内存的长度。在平常我们可能会只注意内存的首地址,对于长度却忽略了。malloc(0) 在这个程序中申请到的内存起始地址为 0x82c3008,长度为 0。

但是我们在程序里不停写 malloc(0),会造成内存泄漏吗?答案是肯定的,因为malloc 实际分配的内存可能会比请求的多,目前的操作系统一般都是 4 字节对齐的,所以写 malloc(0) 系统实际返回的字节数也许就是 4 字节。

四、calloc 和 realloc

malloc 的同胞兄弟

void* calloc(size_t num, size_t size);

void* realloc(void* pointer, size_t new_size);

calloc 的参数代表所返回内存的类型信息

  • calloc 会将返回的内存初始化为 0

realloc 用于修改一个原先已经分配的内存块大小

  • 在使用 realloc 之后应该使用其返回值

  • 当 pointer 的第一个参数为 NULL 时,等价于 malloc

下面看一个 calloc 和 realloc 的使用示例:

#include #include  #define SIZE 5 int main(){    int i = 0;    int* pI = (int*)malloc(SIZE * sizeof(int));    short* pS = (short*)calloc(SIZE, sizeof(short));        for(i = 0; i < SIZE; i++)    {        printf("pI[%d] = %d, pS[%d] = %d\n", i, pI[i], i, pS[i]);    }        printf("Before: pI = %p\n", pI);        pI = (int*)realloc(pI, 2 * SIZE * sizeof(int));        printf("After: pI = %p\n", pI);        for(i = 0; i < 10; i++)    {        printf("pI[%d] = %d\n", i, pI[i]);    }        free(pI);    free(pS);        return 0;}

输出结果如下:

malloc 只负责申请空间,不负责初始化,这里的 pI 指针保存的值均为 0 只是巧合罢了,另外使用 realloc 重置之后,内存地址也会改变,pI 指针保存的值也会改变,这里都为 0 同样也是巧合。

关于"C语言动态内存分配怎么使用"这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对"C语言动态内存分配怎么使用"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。

内存 动态 分配 数组 语言 地址 长度 全局 参数 字节 空间 系统 函数 实际 知识 程序 结果 编译 输出 不同 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 科技信息互联网 深圳互联网络科技有限公司 友谊互联网络科技 广西互联网科技公司 润盈互联网科技 互联网科技公司有哪些 互联网科技美容 互联网养老 桔豆科技 互联网科技大会案例 科技伦理 互联网公司 科技大学互联网专业好不好 科技互联网的估值 温州喔噻互联网科技有限公司 宁夏科技产业互联网案例 中国航天科技大学国际工业互联网 国大互联网教育科技有限公司工作 本届互联网博览会上的黑科技 朱啸虎曾投资哪些互联网科技企业 银川新华互联网科技学校是国营吗 现代科技的标志之一的互联网 互联网科技卖菜 中正互联网科技招聘 老年人脱离互联网科技的作文 团飞科技与伯堂互联网服务平台 广东工业互联网大赛深圳学泰科技 广州燕处互联网科技有限公司 唯美互联网科技 兰石爱特工业互联网科技分公司 科技互联网专业务虚会材料 颐高云石互联网科技
0