| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> C语言之动态内存管理 -> 正文阅读 |
|
[C++知识库]C语言之动态内存管理 |
目录 说到内存管理,我们要先了解一下什么是内存: 一、内存分配——静态存储区,栈区,堆区内存的基本构成:
(1)静态存储区:?主要存放static静态变量、全局变量、常量。这些数据内存在编译的时候就已经为他们分配好了内存,生命周期是整个程序从运行到结束。 (2)栈区:存放局部变量。在执行函数的时候(包括main这样的函数),函数内的局部变量的存储单元会在栈上创建,函数执行完自动释放,生命周期是从该函数的开始执行到结束。 (3)堆区:程序员自己申请一块任意大小的内存—也叫动态内存分配。这块内存会一直存在知道程序员释放掉。C语言中,用malloc or new 动态地申请内存,用free?or?delete释放内存。良好习惯:若申请的动态内存不再使用,要及时释放掉,否则会造成内存泄露。 内存空间具体划分如下:(之后会重点讲堆区的动态内存开辟) 二、为什么存在动态内存分配我们已经掌握和了解到的内存开辟方式是通过数据类型来定义变量,然后操作系统在栈区、静态区或者字符常量区上为该变量分配空间
但是上述的开辟空间的方式有两个特点:
1. 空间开辟大小是固定的。
2. 数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配。
但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道,
那数组的编译时开辟空间的方式就不能满足了。 这时候就只能试试动态存开辟了。
三、动态内存函数的介绍(1)malloc函数?函数作用:向内存申请一块连续可用的空间,并返回指向这块空间的指针。 函数参数:
函数使用:?
结果如下:? malloc函数其实有两种写法:
(2)free函数?? ? ? ?free函数主要是用于在堆区动态内存开辟的一个空间,需要程序员主动调用这个函数来释放空间,堆区不会自己释放空间,而我们一旦使用动态内存开辟的函数,比如malloc、realloc、calloc 开辟空间使用完忘记释放时,就会造成内存泄露(相当于你向内存申请了一块空间,但是你使用完之后不归还,这样别人也用不了这块空间了,虽然这块空间还存在,但是相当于没有了),然后就会发现随着程序在不断运行,可供使用的空间将会越来越少,所以说,内存泄漏是我们在动态内存开辟中会犯的一个常见的错误。 ? ? ? 不过,当我们电脑关机时,操作系统会自动回收动态内存开辟的空间,这就是说为什么电脑关机可以解决大部分问题。 函数作用:用来释放开辟的动态内存 函数参数:
函数使用:?在使用free函数时,前面一定要有动态内存开辟的函数,比如malloc、realloc、calloc。如果参数ptr不是指向动态开辟的,那么free函数是未定义的。 (3)calloc函数?函数作用:calloc 函数的功能和 malloc 十分相似,都是向堆区申请一块空间并返回空间的起始地址,但是 calloc 函数比 malloc 函数多了一个操作,那就是会将申请的空间里面数据全部初始化为0。 函数参数:
函数使用 :
结果如下:? (4)realloc函数函数作用:调整已开辟的动态空间的大小 函数参数:
函数使用 :
?结果如下: realloc函数注意事项:
realloc在调整内存空间的时候会存在两种情况:
情况
1
原有空间的后面有足够大的空间,可以让我们申请。这时扩展内存就在原有内存之后直接追加空间,原来空间的数据不发生变化。
情况
2
原有空间之后没有足够多的空间时,这时 realloc 函数会在堆空间上另找一个合适大小的连续空间来使用,这样函数返回的是一个新的内存地址,所以我们在使用 realloc 函数的时候不要直接将重新调整的空间地址直接赋值给源空间地址,而是应该先进行空指针判断,避免开辟失败的同时还将源空间搞丢,造成内存泄漏;
四、常见动态内存错误(1)、对NULL指针的解引用操作malloc、calloc、realloc 这些函数向内存申请空间是有可能会失败的,申请失败函数就会返回空指针,如果我们不对函数的返回值进行判断,而直接对其解引用的话,就会造成程序崩溃;例如:
(2)、对动态开辟空间的越界访问
?(3)、对非动态开辟内存使用free释放
(4)、使用free释放一块动态开辟内存的一部分?当我们成功开辟一块动态空间并将它交由一个指针变量来管理时,我们可能会在后面的程序中让该指针变量自增,从而让其不再指向该动态空间的起始位置,而是指向中间位置或者结尾,这时我们在对其进行free操作时,也会导致程序崩溃,因为free函数必须释放一整块动态内存,而不能释放它的一部分。
(5)、对同一块动态内存多次释放?
(6)、动态开辟内存忘记释放(内存泄漏)?下面我举一个可能造成内存泄漏的经典案例:
没有用free函数导致内存泄漏?,
切记:
动态开辟的空间一定要释放,并且正确释放 。
|
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/11 12:34:56- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |