【C/C++】静态内存分配与动态内存分配

这篇具有很好参考价值的文章主要介绍了【C/C++】静态内存分配与动态内存分配。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【C/C++】 静态内存分配与动态内存分配

I - 内存分配概述

1.1 - 定义概述


内存分配 (Memory Allocation) 是指为计算机程序或服务分配物理内存空间或虚拟内存空间的一个过程。通常在程序执行前或执行时完成内存分配。

1.2 - 分类概述


存在两种类型的内存分配:

  • 编译时内存分配或静态内存分配 (Compile-time or Static Memory Allocation)
  • 运行时内存分配或动态内存分配 (Run-time or Dynamic Memory Allocation)

静态内存分配

静态内存分配是由编译器为声明的变量分配内存。内存的地址可以通过地址操作符找到,并且可以赋值给指针变量。该内存是在编译时分配的。

动态内存分配

在程序执行时 (execution) 或 运行时 (run-time) 进行的内存分配被称为动态内存分配。库函数例如 calloc()malloc() 或者操作符 new 均支持分配动态内存。动态分配的内存空间,通过这些函数或操作符的返回值分配,赋值给指针变量。

1.3 - 区别概述


序号 静态内存分配 动态内存分配
1 在静态内存分配中,变量被永久地分配内存,直到程序执行结束/函数调用结束 在动态内存分配中,只有当你的程序单元被激活时才会为变量分配内存
2 静态内存分配在程序执行前完成 动态内存分配在程序执行过程中完成
3 使用栈来管理静态分配的内存 使用堆来管理动态分配的内存
4 较不高效 (less efficient) 较高效
5 在静态内存分配中,不存在内存的重用 在动态内存分配中,存在内存的重用,而且在不需要时可以内存可以被释放
6 在静态内存分配中,一旦内存被分配,内存大小就不能再改变 在动态内存分配中,分配了内存后,内存的大小可以改变
7 在静态内存分配方案中,我们不能重新使用未使用的内存 动态内存分配中,允许重复使用内存。用户可以在需要时分配更多的内存。同时,用户也可以在需要时释放内存。
8 在这种内存分配方案中,执行速度比动态内存分配要快 在这种内存分配方案中,执行速度要比静态内存分配慢
9 编译时内存分配 运行时内存分配
10 静态分配的内存从程序开始保持到程序结束 动态分配的内存可以在任意时刻释放
11 静态的内存分配常常用于数组等 动态的内存分配常常用于链表等数据结构

II - 静态内存分配


内存必须被分配给我们所创建的变量,这样实际的变量才能存在。现在有一个问题,即我们认为它是如何运行的,以及它实际上是如何运行的?

计算机如何创建一个变量?

当我们思考如何创造某样东西时,我们会想到“从零开始”着手干,而当计算机创建一个变量 ‘X’ 时,实际上情况并不是这样;对于计算机而言,更像是一种分配,计算机只是从许多预先存在的内存单元中分配一个内存单元给 X。

那么什么是静态内存分配?当我们声明变量时,我们实际上是在准备所有会被使用的变量,这样编译器就知道被使用的变量实际上是用户想要的程序的重要部分,而不是到处漂浮的流氓符号。因此,当我们声明变量时,编译器实际做的是将这些变量分配到它们的房间(一个内存单元)。现在,可以看出,这是在程序执行前完成的,你不能在程序执行时用这种方法分配变量。

示例

void func()
{
	int a;
}

int main()
{
	int b;
	int c[12];
	//...
}

上述代码中所有的变量都是静态分配的。

III - 动态内存分配


那么,既然已经存在一种方式来完成内存分配的工作,为什么我们需要引入另一种分配方法?为什么我们需要在程序执行过程中分配内存?

因为,尽管不是很显而易见,但不能在运行时分配内存,就降低了灵活性,并与空间效率相妥协。特别是,在那些事先不知道输入的情况下,我们会在存储的低效使用和缺乏或过多的空间用来输入数据方面受到影响(给定一个固定长度的数组或类似的数据结构来存储数据)。

所以引入动态内存分配: 在运行时,存储/内存/单元可以分配给变量的机制被称为动态内存分配(不要与 DMA 相混淆)。因此,我们可以知道在运行期间分配内存,这使我们能够使用我们想要的存储,而不用担心任何浪费或者不足。

为什么要使用动态分配的原因

  1. 当我们事先不知道程序需要多少内存的时;
  2. 当我们希望数据结构没有固定的内存空间上限时;
  3. 当你想更有效地使用你的内存空间时。例如: 如果你为一个一维数组分配的内存空间是 array[20],而你最终只使用了 10 个内存空间,那么剩下的 10 个内存空间就被浪费了,这些浪费的内存甚至不能被其他程序变量所使用;
  4. 动态创建的列表的插入和删除可以非常容易地通过操作地址来完成,而在静态分配的内存中,插入和删除会导致更多的移动和内存浪费;
  5. 当你想在编程中使用结构和链表的概念时,动态内存分配是必须的

C++ 代码

int main(int argc, char* argv[])
{
	// 动态内存分配
	int* ptr = new int;
	int* ptr1 = new int[10];

	// 动态分配内存的释放
	delete ptr;
	delete [] ptr1;
}

C 代码

ptr = calloc(m, n);

等价于

ptr = malloc(m * n);
memset(ptr, 0, m * n);

IV - 小结


有两种类型的可用内存 – 栈 (stack) 和堆 (heap)。静态内存分配只能在栈上进行,而动态内存分配可以在栈和堆上进行。在堆上进行动态分配的一个例子是递归,在递归中,函数按照出现的顺序被放入调用堆,并在到达基数时一个一个地弹出。

当在堆上分配内存时,我们需要手动删除内存,因为即使分配的内存范围结束(如栈的情况),内存也不会被编译器自己释放(取消分配 deallocate)。

4.1 - 静态分配的优缺点


优点

  • 使用简单
  • 分配和取消分配都由编译器完成
  • 高效的执行时间
  • 它使用栈数据结构

缺点

  • 内存浪费问题
  • 必须知道确切的内存需求
  • 一旦初始化后,内存的大小不能调整

4.2 - 动态分配的优缺点


优点

  • 动态分配是在运行时进行的
  • 只要我们需要,我们就可以分配(创建)额外的存储
  • 只要我们使用结束了,内存就可以被取消分配(free / delete)动态空间
  • 因此,人们总是可以准确地拥有所需的空间量–不多也不少。
  • 如果需要,内存大小可以重新分配

缺点

  • 由于内存是在运行时分配的,因此需要更多的时间。
  • 当完成后,内存需要由用户释放。这一点很重要,因为它更有可能变成难以发现的 bug。

总上所述,静态内存是编译器提前分配的东西。而动态内存是在执行过程中由程序控制的东西。程序可以要求更多的内存,也可以删除部分分配的内存。
`文章来源地址https://www.toymoban.com/news/detail-500917.html

到了这里,关于【C/C++】静态内存分配与动态内存分配的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 动态分配内存与释放

    1.malloc malloc()可以找到一个大小合适的块。 内存是匿名的,也就是说,malloc()分配了内存,但没有为它指定名字。 格式如下: double*ptd; ptd=(double*)malloc(30*sizeof(double)); ps:ptd可以看成是一个数组。 malloc()可能分配不到所需的内存。在这种情况下,该函数返回空指针。

    2024年01月17日
    浏览(48)
  • C++ 指针进阶:动态分配内存

    malloc 是 stdlib.h 库中的函数,原型为 void *__cdecl malloc(size_t _Size); : 作用 : malloc 函数沿空闲链表(位于内存 堆空间 中)申请一块满足需求的内存块,将所需大小的内存块分配给用户剩下的返回到链表上; 并返回指向该内存区的首地址的指针,意该指针的类型为 void * ,因此

    2024年02月05日
    浏览(29)
  • C++类和动态内存分配

    C++能够在程序运行时决定内存的分配,而不是只在编译阶段,因此,就可以根据程序的需要,而不是根据一系列严格的存储类型规则来使用内存,C++使用new和delete运算符来动态控制内存,但是,在类中使用这些运算符会导致许多新的问题,在这种情况下,析构函数就是必不可

    2024年04月16日
    浏览(32)
  • 【进阶C语言】动态内存分配

    本章大致内容介绍: 1.malloc函数和free函数 2.calloc函数 3.realloc函数 4.常见错误案例 5.笔试题详解 6.柔性数组 1.malloc函数 (1)函数原型 函数参数: 根据用户的需求需要开辟多大的字节空间,为无符号的字节。 返回值: malloc函数成功开辟内存后,会返回该内存的起始地址,可

    2024年02月07日
    浏览(37)
  • 超详细——动态内存分配+柔性数组

    ☃️个人主页:fighting小泽 🌸作者简介:目前正在学习C语言和数据结构 🌼博客专栏:C语言学习 🏵️欢迎关注:评论👊🏻点赞👍🏻留言💪🏻 我们已经学会的内存开辟方式有:创建一个变量,创建一个数组 我们创建一个整形变量就会申请4个字节,创建个数组就会申请

    2023年04月15日
    浏览(32)
  • 数据结构:动态内存分配+内存分区+宏+结构体

    1.定义一个学生结构体,包含结构体成员:身高,姓名,成绩;定义一个结构体数组有7个成员,要求终端输入结构体成员的值,根据学生成绩,进行冒泡排序。 1.申请一个10个int类型的堆区空间,并实现选择排序(需要导入头文件 #include stdlib.h) 2.用##拼接带参宏的参数 3.宏函

    2024年02月20日
    浏览(34)
  • 深入挖掘C语言 ----动态内存分配

    开篇备忘录: \\\"自给自足的光, 永远都不会暗\\\" 正文开始 C语言提供了一个动态开辟内存的函数; 这个函数向内存申请一块连续可用的空间, 并返回指向这块空间的指针. 如果内存开辟成功, 则返回一个指向开辟好空间的指针 如果开辟失败, 则返回一个NULL指针, 因此malloc的返回值一

    2024年04月28日
    浏览(28)
  • 详解C语言—动态内存分配(二)

    目录 前言: 几个经典的例题题 例一: 例二: 例三: 例四: 例五:   C/C++程序的内存开辟 柔性数组 柔性数组的特点: 柔性数组的使用:  柔性数组的代替: 柔性数组的优势: 小结: 希望在复习完详解C语言—动态内存分配(一)​​​​​​​,阅读此篇文章会进一步提升

    2024年02月08日
    浏览(31)
  • 【C\C++】内存分配 和 动态内存管理方式

    如上图所示:在C/C++中,有几个重要的内存区域,每个区域都有不同的意义和用途。我们从内存分配的角度来分析C++各个内存区域的含义: 栈(Stack) :栈是用于 存储 局部变量、函数参数以及函数调用信息 的内存区域 。它的特点是 自动分配和释放 ,并且遵循 后进先出的原

    2024年02月08日
    浏览(33)
  • C语言 malloc动态内存分配函数

    malloc函数:malloc时动态内存分配函数,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址,就是当数组创建长度不一定 害怕数据存储不够或者不能浪费时间 在使用malloc开辟空间时,使用完成一定要释放空间,如果不释放会造内存泄漏。n在使用ma

    2024年02月07日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包