C语言中如何进行内存管理

主页:17_Kevin-CSDN博客

收录专栏:《C语言》

C语言是一种强大而灵活的编程语言,但与其他高级语言不同,它要求程序员自己负责内存的管理。正确的内存管理对于程序的性能和稳定性至关重要。


一、引言

C 语言是一门广泛使用的编程语言,它为程序员提供了对内存的直接控制能力。这种对内存的控制使得 C 语言非常灵活,但也带来了更大的责任。在 C 语言中,程序员需要负责内存的分配和释放,否则可能会导致内存泄漏和其他内存管理问题。本文将深入探讨 C 语言的内存管理机制,包括内存分配、内存释放、内存泄漏等问题。

二、内存分配

C语言中有三种内存分配方式:

  • 静态内存分配
  • 栈内存分配
  • 动态内存分配

静态内存分配

静态内存分配:静态内存分配是在程序编译时进行的,它将内存分配给全局变量和静态变量。全局变量和静态变量的内存空间在程序运行期间一直存在,直到程序结束。静态内存分配的优点是内存分配和释放的效率高,缺点是内存使用不灵活,无法根据需要动态调整内存大小。

当我们创建变量的时候,系统将会自动的为变量分配空间:

//创建变量a
int a = 0;

可以观察到当创建变量a后系统会为a分配一块内存,这就是静态内存的分配。

栈内存的分配

栈内存分配是在程序运行时进行的,它将内存分配给函数内部的局部变量。栈内存的空间是有限的,当函数执行完毕后,栈内存会自动释放。栈内存分配的优点是内存管理简单,缺点是内存空间有限,不适合分配大内存。

例如:

当创建一个函数,在函数中创建一个变量local_num,和local_name

void test()
{int local_num = 17;char local_name = "Kevin";}int main()
{test();return 0;
}

 当调试时走过这两个局部变量但没有走出函数时可以观察到这两个变量成功的创建了:

 当走出函数后刷新即可发现两个变量变成了未标识变量:

这就是在函数中的栈内存分配,随用随分配,在用过后就销毁。

动态内存分配

动态内存分配是在程序运行时根据需要进行的内存分配。它使用 malloc() 函数或 calloc() 函数来分配内存空间,使用 free() 函数来释放内存空间。动态内存分配的优点是内存使用灵活,可以根据需要动态调整内存大小,缺点是内存管理复杂,容易出现内存泄漏等问题。

具体函数的使用可以翻阅博主这篇博客进行查阅

C/C++ (stdio.h)标准库详解-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/SDFsoul/article/details/135568683

1. malloc

malloc() 函数用于分配指定大小的内存块

int main() 
{int* ptr;// 分配 10 个整数的内存块ptr = (int*)malloc(10 * sizeof(int));if (ptr == NULL) {printf("内存分配失败\n");exit(1);}// 访问分配的内存for (int i = 0; i < 10; i++) {ptr[i] = i + 1;}// 输出分配的内存中的值for (int i = 0; i < 10; i++) {printf("%d ", ptr[i]);}printf("\n");// 释放内存free(ptr);return 0;
}

在上述示例中,malloc() 函数用于分配 10 个整数的内存块。如果内存分配成功,ptr 将指向分配的内存块,否则输出错误信息并退出程序。然后,可以通过 ptr 访问和修改分配的内存。最后,使用 free() 函数释放分配的内存块。

2. calloc

calloc() 函数用于分配指定数量的元素,并将它们初始化为 0

#include <stdio.h>
#include <stdlib.h>int main() 
{int* ptr;// 分配 10 个整数的内存块,并将它们初始化为 0ptr = (int*)calloc(10, sizeof(int));if (ptr == NULL) {printf("内存分配失败\n");exit(1);}// 访问分配的内存for (int i = 0; i < 10; i++) {printf("%d ", ptr[i]);}printf("\n");// 释放内存free(ptr);return 0;
}

在上述示例中,calloc() 函数用于分配 10 个整数的内存块,并将它们初始化为 0。如果内存分配成功,ptr 将指向分配的内存块,否则输出错误信息并退出程序。然后,可以通过 ptr 访问和修改分配的内存。最后,使用 free() 函数释放分配的内存块。

3. free

free() 函数用于释放之前分配的内存块,在上文malloc和calloc中均用到了free函数,目的就是在使用完分配的内存块后进行释放,避免内存泄漏。

三、内存释放

在 C 语言中,内存释放是非常重要的。如果忘记释放不再使用的内存,就会导致内存泄漏。内存泄漏会导致程序的性能下降,甚至可能导致程序崩溃。在 C 语言中,有两种常见的内存释放方式:手动释放和自动释放。

1. 手动释放

手动释放是指程序员使用 free() 函数来释放不再使用的内存空间。在使用动态内存分配时,程序员需要在不再使用内存空间时手动调用 free() 函数来释放内存。

#include <stdlib.h>int* allocate_memory(int size) 
{int* memory = (int*)malloc(size * sizeof(int));if (memory == NULL) {printf("内存分配失败\n");exit(1);}return memory;
}void free_memory(int* memory) 
{if (memory != NULL) {free(memory);}
}int main() 
{int* dynamic_memory = allocate_memory(10);for (int i = 0; i < 10; i++) {dynamic_memory[i] = i + 1;}for (int i = 0; i < 10; i++) {printf("%d ", dynamic_memory[i]);}printf("\n");free_memory(dynamic_memory);return 0;
}
  1. allocate_memory 函数用于动态分配一块大小为 size 个整数的内存空间,并返回指向该内存空间的指针。如果内存分配失败,程序会输出提示信息并调用 exit(1) 来退出程序。

  2. free_memory 函数用于释放动态分配的内存空间,首先检查指针是否为空,然后调用 free 函数进行内存释放。

  3. main 函数中,首先调用 allocate_memory 函数分配了包含 10 个整数的内存空间,并将返回的指针赋值给 dynamic_memory。然后使用循环给动态分配的内存赋值,并输出每个元素的值。

  4. 最后,通过调用 free_memory 函数释放动态分配的内存空间,避免内存泄漏。

2. 自动释放

自动释放是指在某些情况下,C 语言的编译器会自动释放不再使用的内存空间。例如,当函数执行完毕后,编译器会自动释放函数内部的栈内存。

#include <stdio.h>void function() 
{int local_variable = 30;printf("局部变量的值:%d\n", local_variable);
}int main() 
{function();return 0;
}

四、内存泄漏

内存泄漏指程序在不再需要使用内存时未将其释放,导致系统内存资源浪费。内存溢出则是指程序访问超出了已分配内存块的范围(例如数组越界访问)。


五、指针和内存

在C语言中,指针与内存密切相关。我们可以通过指针指向目标地址来直接操作内存,包括访问、修改和释放内存。

指针数组

int *ptrArray[10]; // 声明一个包含10个整型指针的数组

二级指针

int **pptr; // 声明一个二级整型指针
int value = 100;
int *ptr = &value;
pptr = &ptr; // 将ptr的地址赋给pptr

指针与结构体

结构体和指针的结合也是C语言中常见的用法,可以方便地操作复杂的数据结构(例如链表)。


希望这能帮助您更好地理解和应用C语言中的内存管理知识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/708291.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VPX基于全国产飞腾FT-2000+/64核+复旦微FPGA的计算刀片

6U VPX计算板 产品简介 产品特点 飞腾计算平台&#xff0c;国产化率100% VPX-MPU6902是一款基于飞腾FT-2000/64核的计算刀片&#xff0c;主频2.2GHz&#xff0c;负责业务数据流的管控和调度。搭配自带独立显示芯片的飞腾X100芯片&#xff0c;可用于于各类终端及服务器类应用场…

spring boot整合cache使用memcached

之前讲了 spring boot 整合 cache 做 simple redis Ehcache 三种工具的缓存 上文 windows系统下载安装 memcached 我们装了memcached 但spring boot没有将它的整合纳入进来 那么 我们就要自己来处理客户端 java历史上 有过三种客户端 那么 我们用肯定是用最好的 Xmemcached …

vue2 + axios + mock.js封装过程,包含mock.js获取数据时报404状态的解决记录,带图文,超详细!!!

vue axios mock.js 以下是封装的过程&#xff0c;记录一下 1、首先先了解什么是mock.js的用途及特点 官网地址&#xff1a;Mock.js (mockjs.com) 作用&#xff1a;生成随机数据&#xff0c;拦截 Ajax 请求 优势&#xff1a; 2、了解axios的原理及使用 官网地址&#xff1a…

大模型(LLM)的token学习记录-I

文章目录 基本概念什么是token?如何理解token的长度&#xff1f;使用openai tokenizer 观察token的相关信息open ai的模型 token的特点token如何映射到数值&#xff1f;token级操作&#xff1a;精确地操作文本token 设计的局限性 tokenizationtoken 数量对LLM 的影响训练模型参…

研发日记,MatlabSimulink开箱报告(九)——Simulink Test模块

文章目录 前言 Simulink Test模块 静态测试 动态测试 逻辑测试 前言 见《开箱报告&#xff0c;Simulink Toolbox库模块使用指南&#xff08;四&#xff09;——S-Fuction模块》 见《开箱报告&#xff0c;Simulink Toolbox库模块使用指南&#xff08;五&#xff09;——S-F…

练习 2 Web [ACTF2020 新生赛]BackupFile 1

[ACTF2020 新生赛]BackupFile 1 Web常规题目 首先尝试查找常见的前端页面index.php之类的&#xff0c;没找到 题目有个“BackupFile”——备份文件 尝试用工具遍历查找相关的文件 御剑没扫出来&#xff0c;搜索搭建好dirsearch后&#xff0c;扫出来的index.php.bak 扫描工…

迟到的VNCTF2024逆向题WP

这次比赛因为有事外出&#xff0c;只做了前两题&#xff0c;最近有空才把另外3题也做出来&#xff0c;总体来说比以往的VNCTF逆向题目要难一些。当然也有可能是我水平退步了&#xff0c;就算有时间参加比赛&#xff0c;应该也做不完这5题。VN的小伙伴越来越厉害了&#xff0c;出…

猜猜心里数字(个人学习笔记黑马学习)

1.定义一个变量&#xff0c;数字类型&#xff0c;内容随意 2.基于input语句输入猜想的数字&#xff0c;通过if和多次elif的组合&#xff0c;判断猜想数字是否和心里数字一致 num5if int(input("请输入第一次猜想的数字&#xff1a;"))5:print("猜对了&#xff0…

ROS 2基础概念#1:计算图(Compute Graph)| ROS 2学习笔记

在ROS中&#xff0c;计算图&#xff08;ROS Compute Graph&#xff09;是一个核心概念&#xff0c;它描述了ROS节点之间的数据流动和通信方式。它不仅仅是一个通信网络&#xff0c;它也反映了ROS设计哲学的核心——灵活性、模块化和可重用性。通过细致探讨计算图的高级特性和实…

Java中使用Jsoup实现网页内容爬取与Html内容解析并使用EasyExcel实现导出为Excel文件

场景 Pythont通过request以及BeautifulSoup爬取几千条情话&#xff1a; Pythont通过request以及BeautifulSoup爬取几千条情话_爬取情话-CSDN博客 Node-RED中使用html节点爬取HTML网页资料之爬取Node-RED的最新版本&#xff1a; Node-RED中使用html节点爬取HTML网页资料之爬…

远程服务器Ubuntu 18.04安装VNC远程桌面

一、安装vnc 1.安装图形化界面工具 # 安装过程中会弹窗让选择配置&#xff0c;选lightdm sudo apt install ubuntu-desktop sudo apt-get install gnome-panel gnome-settings-daemon metacity nautilus gnome-terminal 2.安装vnc sudo apt-get install x11vnc3.安装LightD…

ifcplusplus 示例 函数中英文 对照分析

有需求&#xff0c;需要分析 ifc c渲染&#xff0c;分析完&#xff0c;有 230个函数&#xff0c;才能完成一个加载&#xff0c;3d加载真的是大工程&#xff01; 函数中英文对照表&#xff0c;方便 日后开发&#xff0c;整理思路顺畅&#xff01;&#xff01;&#xff01;&#…

线性规划基础

利用一个简单的实例来介绍什么事线性规划&#xff0c;假设如果有一家巧克力工厂需要生产两种不同类型的巧克力&#xff0c;分别是类型A和类型B&#xff0c;两种巧克力用到的原材料是一样的&#xff0c;都是使用牛奶和可可两种材料&#xff0c;主要的区别是在与这两种原料的配料…

C语言实现21点游戏【单人模式,双人模式,单-多电脑模式】,21点又名黑杰克(英文:Blackjack)

项目背景&#xff1a; 21点又名黑杰克&#xff08;英文&#xff1a;Blackjack&#xff09; &#xff0c;起源于法国&#xff0c;已流传到世界各地。21点&#xff0c;是一种使用扑克牌玩的赌博游戏。亦是唯一一种在赌场中可以在概率中战胜庄家的一种赌博游戏。 现在在世界各地…

k8s初始化报错 [ERROR CRI]: container runtime is not running: ......

一、环境参数 linux系统为centos7kubernetes版本为v1.28.2containerd版本为1.6.28 二、报错内容 执行初始化命令kubeadm init命令时报错&#xff0c;内容如下 error execution phase preflight: [preflight] Some fatal errors occurred:[ERROR CRI]: container runtime is…

C++观察者模式代码实例

文章目录 C观察者模式代码实例一C观察者模式代码实例二 C观察者模式代码实例一 下面是一个简单的C观察者模式的实现示例&#xff0c;这里仅给出核心代码框架&#xff0c;完整的工程应包含对应的头文件声明及必要的#include指令等。 // 观察者接口&#xff08;Observer&#x…

【Unity实战】UGUI和Z轴排序那点事儿

如果读者是从Unity 4.x时代过来的&#xff0c;可能都用过NGUI这个插件&#xff08;后来也是土匪成了正规军&#xff09;&#xff0c;NGUI一大特点是可以靠transform位移的Z值进行遮挡排序&#xff0c;然而这个事情在UGUI成了难题&#xff08;Sorting Layer、Inspector顺序等因素…

品牌百度百科应该怎样创建?编辑品牌百度百科词条的秘籍!

在数字化时代&#xff0c;品牌的故事不仅仅存在于广告牌和电视屏幕上&#xff0c;它们还在互联网的每一个角落悄然讲述。百度百科词条作为中国最大的中文百科全书&#xff0c;成为了品牌展示自身故事的重要舞台。那么&#xff0c;如何在这个舞台上留下你的品牌印记呢&#xff1…

solidity编程

一.Solidity 简介 Solidity 是⼀种⽤于编写以太坊虚拟机&#xff08; EVM &#xff09;智能合约的 编程语⾔。我认为掌握 Solidity 是参与链上项⽬的必备技 能&#xff1a;区块链项⽬⼤部分是开源的&#xff0c;如果你能读懂代码&#xff0c;就可以 规避很多亏钱项⽬。…

RK3568 android11 调试陀螺仪模块 MPU-6500

一&#xff0c;MPU6500功能介绍 1.简介 MPU6500是一款由TDK生产的运动/惯性传感器&#xff0c;属于惯性测量设备&#xff08;IMU&#xff09;的一种。MPU6500集成了3轴加速度计、3轴陀螺仪和一个板载数字运动处理器&#xff08;DMP&#xff09;&#xff0c;能够提供6轴的运动…