C语言--内存管理

内存管理

内存分区

C语言中,定义了四个内存空间:代码区、全局变量与静态变量区(静态存储区)、局部变量区即栈区、动态存储区即堆区。

  1. 代码区:主要存放程序中的代码,属性为只读。(也叫.text段)

  2. 全局变量与静态变量区:也称静态存储区,该块内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在,如:全局变量、静态变量、字符串常量。当程序结束的时候才释放该块内存。

    该块内存也可分为以下几个分区:
    data段—>存放初始化过的静态变量、全局变量等
    bss段—>存放未初始化过的静态变量、全局变量等,一般会被编译器默认初始化为0。
    rodata段—>即只读存储区,用来存放字符串常量、const修饰的变量等

  3. 栈区:函数内局部变量的存储区域,函数执行完后其会被自动释放,函数调用时才给分配内存。系统会自动帮助我们申请和释放,但缺点是栈的空间有限,在Linux系统中栈的空间容量为8M。(和动态内存分配不同这个内存不需要程序员自己去管理,我们只需要拿来用,操作系统会帮我们去管理该块内存)

  4. 堆区:有些对象只有在程序运行时才能确定存储空间,无法为他们预先分配空间,只能在程序运行时才能为他们分配内存。所以也叫动态分配,动态内存的生存期有程序员决定。(其实就是你何时malloc以及何时free)

一图胜千言,为了彻底说清楚这个问题,专门画了张图,下图展示了一个可执行程序ELF格式的构造:
在这里插入图片描述
我们知道,源代码编译成程序,程序是放在硬盘上的,而非内存里!只有执行时才会被复制到内存中!我们来看看程序结构,ELF是是Linux的主要可执行文件格式。

ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)

  • Program header描述的是一个段在文件中的位置、大小以及它被放进内存后所在的位置和大小

  • Section头表(section header table)包含了描述文件sections的信息。每个section在这个表中有一个入口;每个入口给出了该section的名字,大小,等等信息。相当于 索引!

  • 正文段上面是常量区,常量区上面是全局变量和静态变量区,二者占据的就是初始化的数据和未初始化的数据那部分;

  • 再上面就是堆,动态存储区,这里是上增长;

  • 堆上面是栈,存放的是局部变量,就是局部变量所在代码块执行完毕后,这块内存会被释放,这里栈区是下增长;

    最终程序文件的大小由.text,.data,.rodata决定,如此我们在对自己的code进行内存优化的时候就知道从哪里去入手了。

动态内存

  • 只有动态内存才能分配和释放
  1. 动态内存的申请

    void *malloc(size_t size);

    • 该函数只关心申请内存的大小
    • 申请的是一块连续的内存,返回申请的内存的首地址,若失败返回NULL。(记得要进行出错判断)
    • 该函数返回的是void *类型的指针,所以使用时需要进行强转。
    • 需要显示初始化,堆区不会自动在分配时做初始化的(包括清零),所以申请时需要显示的初始化。
  2. 动态内存的释放

    void free(void *ptr);

    • 需要提供内存的起始地址。
    • 若分配了空间却没有释放,称为内存泄漏。即你的内存会越用越少。
    • malloc应与free配对使用。
    • 不允许重复释放
    • free只能释放堆区空间

野指针的形成原因与解决办法

  1. 野指针是指指向垃圾内存的指针,而不是NULL;
  2. 指针P被free掉了,却没有将其置为NULL。free函数只是将指针所指向的内存释放掉了,使得内存成为自由内存,但是并没有把指针本身的内容清除掉,所以指针仍指向已经释放的动态内存。这是很危险的。
  3. 没有及时初始化指针。
  4. 指针操作超越了变量的作用域范围。如数组越界。
  5. 不要返回指向栈指针内存的指针,因为返回时栈内部才能已经被释放掉了,指针不能再继续访问该块内存。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言-学生信息管理系统是一个基于链表数据结构的学生信息管理系统。链表是一种数据结构,可以存储和管理一系列具有相同类型的数据。在学生信息管理系统中,链表被用来存储和操作学生的基本信息。 该系统主要有以下功能: 1. 添加学生信息:可以添加学生的姓名、学号、性别、年龄等信息,并将该学生的信息节点插入到链表中。 2. 删除学生信息:根据学号或其他关键词查找到对应的学生信息节点,并从链表中删除该节点。 3. 修改学生信息:根据学号或其他关键词查找到对应的学生信息节点,并根据需求修改学生的信息。 4. 查询学生信息:可以根据学号或其他关键词查找到对应的学生信息节点,并显示该学生的详细信息。 5. 遍历学生信息:可以遍历整个链表,显示所有学生的基本信息。 链表的优势在于插入和删除节点的操作比较高效,因为只需要改变节点的指针指向即可,不需要移动其他节点。而数组在插入和删除操作时需要移动其他元素,效率较低。 在实现学生信息管理系统时,可以使用指针来操作链表,通过指针的指向找到链表的某个节点,并进行相应的操作。同时,需要注意对内存管理,确保动态分配和释放内存的正确性,避免内存泄漏和访问错误。 总之,C语言-学生信息管理系统是一个基于链表数据结构的系统,可以实现学生信息的增删改查等功能。通过灵活运用链表的特点,可以高效地管理学生的基本信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值