IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: 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语言内存分配

一、内存区间:

在C/C++中内存分为5个区,分别为栈区、堆区、全局/静态存储区、常量存储区、代码区。?

?栈区:存放函数内的局部变量,形参和函数返回值。栈区之中的数据的作用范围过了之后,系统就会自动回收栈区的内存。

堆区:由程序员手动分配释放的储存区,如果程序员不释放这块内存,内存将一直被占用,直到程序运行结束由系统自动收回。

全局/静态储存区全局变量和静态变量的储存是放在一块(可读写区)的,这块空间当程序运行结束后由系统释放。

只读区:常量字符串以及程序代码储存在这里。

?二、栈、堆区别

堆与栈实际上是操作系统对进程占用的内存空间的两种管理方式,主要有如下几种区别:

1)管理方式不同。栈由操作系统自动分配释放,无需我们手动控制;堆的申请和释放工作由程序员控制,容易产生内存泄漏;

2)空间大小不同。每个进程拥有的栈的大小要远远小于堆的大小。

3)生长方向不同。堆的生长方向向上,内存地址由低到高;栈的生长方向向下,内存地址由高到低。

4)分配方式不同。堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。

5)分配效率不同。栈由操作系统自动分配,会在硬件层级对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是由C/C++提供的库函数或运算符来完成申请与管理,实现机制较为复杂,频繁的内存申请容易产生内存碎片。

6)存放内容不同。栈存放的内容,函数返回地址、相关参数、局部变量和寄存器内容等。堆,一般情况堆顶使用一个字节的空间来存放堆的大小,而堆中具体存放内容是由程序员来填充的。

三、内存操作函数

1、malloc()

头文件:#include <stdlib.h>

函数原型:void* malloc (size_t size);

size 为需要分配的内存空间的大小,以字节(Byte)计。malloc() 在堆区分配一块指定大小的内存空间,用来存放数据。这块内存空间在函数执行完成后不会被初始化,它们的值是未知的。

分配成功返回指向该内存的地址,失败则返回 NULL。

例子:

char *ptr = (char *)malloc(10);  // 分配10个字节的内存空间,用来存放字符

2、calloc()??

头文件:#include <stdlib.h>

calloc() 函数用来动态地分配内存空间并初始化为 0,其原型为:

void* calloc (size_t num, size_t size);??

calloc() 在内存中动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0。所以它的结果是分配了 num*size 个字节长度的内存空间,并且每个字节的值都是0。

【返回值】分配成功返回指向该内存的地址,失败则返回 NULL。??

char *ptr = (char *)calloc(10, 10);  // 分配100个字节的内存空间

3、realloc()

realloc() 会将 ptr 所指向的内存块的大小修改为 size,并将新的内存指针返回。

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

重新分配给定的内存区域。它必须预先分配malloc()calloc()realloc()尚未释放与free或呼叫realloc。否则,结果是不确定的。

重新分配由以下两者之一完成:

a)ptr如有可能,扩大或缩小指定的现有地区。该地区的内容保持不变,直至新旧尺寸中的较小者。如果区域展开,则数组新部分的内容未定义。

b)分配一个大小为new_size字节的新内存块,复制大小等于新旧大小较小者的内存区域,并释放旧块。

如果没有足够的内存,则旧的内存块不会被释放,并返回空指针。如果ptrNULL,则行为与调用mallocnew_size)相同。如果new_size为零,则行为是实现定义的(可能会返回空指针(在这种情况下,可能会释放或不释放旧的内存块),或者可能会返回一些可能不用于访问存储的非空指针)。

【返回值】成功时,将指针返回到新分配的内存的开始位置。返回的指针必须用free()或来解除分配realloc()。原始指针ptr无效,并且对它的任何访问都是未定义的行为(即使重新分配就地)。失败时,返回一个空指针。原始指针ptr仍然有效,可能需要使用free()or 取消分配realloc()

?4、其他

void free(void *ptr)

释放之前调用 calloc、malloc 或 realloc 所分配的内存空间。

void *memchr(const void *str, int c, size_t n)在参数 str 所指向的字符串的前 n 个字节中搜索第一次出现字符 c(一个无符号字符)的位置。
int memcmp(const void *str1, const void *str2, size_t n)把 str1 和 str2 的前 n 个字节进行比较。
void *memcpy(void *dest, const void *src, size_t n)从 src 复制 n 个字符到 dest。

?void *memmove(void *dest, const void *src, size_t n)? ?另一个用于从 src 复制 n 个字符到 dest 的函数,如内存无重叠则和memcpy一样,如果有重叠该函数确保了结果正确,dest的内容会被修改。

void *memset(void *str, int c, size_t n)复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符

?参考地址:常用C语言内存操作函数 - 简书 (jianshu.com)

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-30 11:49:20  更:2021-08-30 11:49:32 
 
开发: 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/28 11:58:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码