当前位置: 首页 > web >正文

C语言-动态内存分配函数、变量属性(全局、局部、静态、只读)、C语言内存结构;

本章概述思维导图:

动态分配内存函数

函数名

英文单词

作用

malloc

memory allocatio

申请空间(连续)

calloc

contiguous allocation

申请空间+数据初始化

realloc

re-allocarion

修改空间大小

free

free

释放空间

动态分配内存函数malloc函数

malloc 是 C 语言标准库中用于动态内存分配的核心函数,定义在 <stdlib.h> 头文件中。它允许程序在运行时从堆(heap)中申请指定大小的内存块,避免静态内存分配的限制。

代码示例:使用malloc函数申请一片空间,要存储10个int类型的整数

#include <stdio.h>
#include <stdlib.h>
int main()
{int *p;p=malloc(sizeof(int)*10);for(int i=0;i<10;i++){printf("现在给第%d个空间赋值\n",i+1);scanf("%d",p+i);}for(int i=0;i<10;i++){printf("现在打印第%d个空间值为:%d\n",i+1,*(p+i));}free(p);return 0;
}

  代码讲解:先引入必要<stdlib.h>头文件,声明一个整型指针p,通过malloc动态分配能存储10个整数的内存空间并检查是否分配成功。接着用循环和scanf让用户为这10个整数赋值,再通过另一个循环用指针算术和解引用读取并打印每个整数值,最后用free释放分配的内存


动态分配内存函数calloc函数

malloc函数和calloc函数的区别:

malloc函数:分配的内存是未初始化的,内存中的内容是随机的、不确定的,可能是之前使用过的残留数据。

calloc函数:会将分配的内存全部初始化为零。这对于需要确保内存初始状态为零的场景非常有用,比如初始化数组或结构体。

代码示例:使用calloc函数申请一片空间,要存储10个char类型的字符

#include <stdio.h>
#include <stdlib.h>
int main()
{char *p;p=calloc(10,sizeof(char));//要传入两个形参,一个是元素的个数,一个是单个元素的大小for(int i=0;i<10;i++){printf("现在给第%d个空间赋值\n",i+1);scanf("%c",p+i);getchar();}for(int i=0;i<10;i++){printf("现在打印第%d个空间值为:%c\n",i+1,*(p+i));}free(p);return 0;
}

代码讲解:通过 calloc 动态分配了能存储 10 个字符的内存空间(自动初始化为 0),然后通过循环用 scanf 让用户依次输入字符并存储到分配的内存中(用 p + i 移动指针位置,getchar() 清除输入缓冲区残留的换行符避免跳过输入),接着再用循环通过指针算术 *(p + i) 逐个打印字符,最后用 free 释放内存防止泄漏。


动态分配内存函数realloc函数

realloc(re-allocate)是 C 语言中用于动态调整已分配内存块大小的函数,属于 <stdlib.h> 库。它可以在运行时扩大或缩小内存空间,避免手动分配新内存和复制数据的麻烦。

代码示例:在上一个calloc代码示例中将原有的10字节内存空间更改为15字节空间

#include <stdio.h>
#include <stdlib.h>
int main()
{char *p;p=calloc(10,sizeof(char));//要传入两个形参,一个是元素的个数,一个是单个元素的大小p=realloc(p,15*sizeof(char));for(int i=0;i<15;i++){printf("现在给第%d个空间赋值\n",i+1);scanf("%c",p+i);getchar();}for(int i=0;i<15;i++){printf("现在打印第%d个空间值为:%c\n",i+1,*(p+i));}free(p);return 0;
}

代码讲解:通过 calloc 动态分配 10 个初始化为 0 的字符内存,再用 realloc 将其扩展至 15 个字符(新增部分未初始化),随后通过循环让用户输入 15 个字符并存储到内存中(用 getchar() 清除缓冲区残留换行符避免输入错乱),最后遍历打印每个字符的值并释放内存。


动态分配内存函数free函数

在C语言中ferr函数用来释放动态分配的内存,避免内存泄漏;(不要小看它,是处理内存泄漏的必要工具);

代码示例:有一个指针P动态分配了10字节的空间,现在需要一分匹配动态内存空间就释放

#include <stdio.h>
#include <stdlib.h>
int main()
{char *p;p=calloc(10,sizeof(char));//要传入两个形参,一个是元素的个数,一个是单个元素的大小free(p);return 0;
}

代码讲解:首先通过 calloc(10, sizeof(char)) 分配 10 个字节的连续内存空间(并自动初始化为 0),返回的指针赋值给 char* p;接着调用 free(p) 释放该内存,防止泄漏。


动态内存分配函数细节

1.动态内存分配函数创建空间单位是字节;

2.动态内存分配函数返回值的是void类型的指针,没有步长的概念,也无法获取空间中的数据,需要强 转

3.malloc返回的仅仅是首地址,没有总大小,最好定义一个变量记录总大小

4.malloc申请的空间不会自动消失,如果不能正确释放,会导致内存泄漏

5.malloc申请的空间过多,会产生虚拟内存

6.malloc申请的空间没有初始值,需要先赋值才能使用

7.free释放完空间后,空间中数据叫做占数据,可能被清空,可能被修改为其他值

8.calloc就是在malloc的基础上多一个初始化的动作

9.realloc修改之后的空间,地址值有可能发生变化,也有可能不会改变,但是原本的数据 不会丢失

10.realloc修改之后,无需释放原来的空间,函数底层会进行处理


C语言变量

全局变量

在 C 语言中,全局变量是在函数外部定义的变量,其生命周期贯穿整个程序运行期间,作用域为整个源文件(或通过 extern 扩展到其他文件)。

生命周期:程序启动时分配内存,结束时释放。在整个程序运行期间;

作用域:默认仅在定义它的源文件内有效(文件作用域),可以通过extern关键字跨文件访问;

初始化:未操控初始化时,自动初始化为0;

存储位置:存储在全局区中的静态存储区(与局部变量不同)


局部变量

在 C 语言中,局部变量是在函数内部或代码块(如 {} 包围的块)中定义的变量,其作用域和生命周期仅限于定义它的函数或代码块。

生命周期:两个情况,1.函数调用时创建,函数返回时销毁(自动释放内存)。2.代码块(如 if/for)中的局部变量在退出块时销毁。

作用域:仅在定义它的函数或代码块内有效,外部不可访问。

初始化:未操控初始化时,自动初始化为随机值;

存储位置:存储在栈空间(stack)


static静态局部变量

在 C 语言中,静态局部变量(static 局部变量)是通过 static 关键字修饰的局部变量,它结合了局部作用域和静态存储期的特性。

生命周期:程序整个运行期间存在(仅初始化一次,不会在函数退出时销毁)。

作用域:限于定义让的函数内(与普通局部变量一致)

初始化:未操控初始化时,自动初始未0;注意点:仅在第一次进入函数时初始化,不会随着函数的结束,初始值清空。后续调用保留上一次的值;

存储位置:存储在全局区中的静态存储区(与全局变量相同);


static静态全局变量

在 C 语言中,静态全局变量(static 全局变量)是通过 static 关键字修饰的全局变量,它限制了变量的链接属性,使其仅在定义它的源文件内可见。

生命周期:程序整个运行期间存在(与普通全局变量相同);

作用域:仅限于定义它的源文件内(通过 static 限制,其他文件无法访问)。

初始化:未操控初始化时,自动初始未0;仅在程序启动时初始化一次;

存储位置:存储在全局区中的静态存储区(与全局变量相同);


const只读变量

在 C 语言中,const 关键字用于定义只读变量(常量),表示该变量的值在初始化后不能被修改。

只读变量特性:const 修饰的变量必须在定义时初始化,之后不能被修改。

存储位置:存储在全局区中的只读常量区;


const关键字修饰指针

int const *p或const int *p;------常量指针,指针指向的值不能改变,可以改变指针指向;

int *const p;------指针常量,指针指向不能改变,可以修改指针指向的值;

int const *const p 或 const int *const p ;----指向常量的指针常量,指向和值均不能修改


C语言内存结构

在 C 语言中,内存通常被划分为 四个主要区域:代码区、全局区、堆( heap )空间、栈( stack )空间;

代码区:在 C 语言的内存布局中,代码区(Text Segment) 是程序运行时存储编译后的机器指令的核心区域。它决定了程序的行为逻辑,且具有严格的访问权限和生命周期特性。

全局区:在 C 语言的内存布局中,全局区(Global Segment) 是用于存储全局变量、静态变量和字符串常量的关键区域。它贯穿程序的整个生命周期,具有特定的权限和生命周期特性。

栈空间:在 C 语言的内存布局中,栈空间(Stack) 是用于存储局部变量、函数参数、返回地址等临时数据的关键区域。它由编译器自动管理,具有高效但有限的特性。

堆空间:在 C 语言中,堆空间(Heap) 是程序运行时用于动态内存分配的区域,与栈空间(自动管理的局部变量存储区)形成互补。堆空间由程序员手动控制分配和释放,适用于存储生命周期不确定、大小可变或需要在多个函数间共享的数据。


制作不易!喜欢的小伙伴给个小赞赞!喜欢我的小伙伴点个关注!有不懂的地方和需要的资源随时问我哟!

http://www.xdnf.cn/news/17587.html

相关文章:

  • go加速配置(下载第三方库)
  • [0CTF 2016]piapiapia
  • 【秋招笔试】2025.08.09美团秋招研发岗机考真题-第二题
  • 在Mac上搭建本地AI工作流:Dify与DeepSeek的完美结合
  • 【2025CVPR-图象分类方向】ProAPO:视觉分类的渐进式自动提示优化
  • 【MySQL——第三章 :MySQL库表操作】
  • STM32 DMAMUX 平台驱动程序注册
  • 机器学习——DBSCAN 聚类算法 + 标准化
  • 解读 GPT-5:从“博士级 AI 专家”能力到 OpenAI API Key 获取与实践(提示工程→性能调优全流程)
  • 【递归、搜索与回溯算法】深度优先搜索
  • Spring AOP 底层实现(面试重点难点)
  • 结构化记忆、知识图谱与动态遗忘机制在医疗AI中的应用探析(上)
  • scikit-learn/sklearn学习|线性回归解读
  • 深度相机---双目深度相机
  • 神经机器翻译(NMT)框架:编码器-解码器(Encoder-Decoder)结构详解
  • tlias智能学习辅助系统--原理篇-SpringBoot原理-自动配置-自定义starter
  • Agent在游戏行业的应用:NPC智能化与游戏体验提升
  • SupChains团队:化学品制造商 ChampionX 供应链需求预测案例分享(十七)
  • Word XML 批注范围克隆处理器
  • 【从汇编语言到C语言编辑器入门笔记9】 - 链接器的执行过程
  • Docker部署到实战
  • K8s四层负载均衡-service
  • Python爬虫实战:研究BlackWidow,构建最新科技资讯采集系统
  • 【话题讨论】GPT-5 发布全解读:参数升级、长上下文与多领域能力提升
  • log4cpp、log4cplus 与 log4cxx 三大 C++ 日志框架
  • MPLS对LSP连通性的检测
  • 力扣559:N叉树的最大深度
  • 【力扣198】打家劫舍
  • Ubuntu 24.04 适配联发科 mt7902 pcie wifi 网卡驱动实践
  • 联邦学习之------VT合谋