堆栈学习总结

 

一:栈(stack)

函数调用之前会将当前存入到栈中。程序中栈是由编译器管理。

入栈,栈指针减小

出栈,栈指针增大

栈遵守先入后出原则

栈只有唯一入口,即栈指针。而堆可以有多个入口。

 

 

在函数中,参数和自动变量都将送入栈区。

 

函数退出后,属于该函数的栈自动释放,此时该栈里的内容不能被别的函数使用,

 

即内层函数可以使用外层函数的栈内存,但外层函数不能使用内层函数的栈内存。

 

实践解决问题

之前要实现将PC机的较大的图像文件写nand flash中,采用main函数设立一个数组变量,将PC机的.bmp图像fread读入,失败,就是因为栈设定太小,无法分配。之后采用全局变量才解决,当时还不知道是这个原因。

 

 

二 堆(heap):

堆内存区域的分配和释放时通过调用库函数来完成的,由程序员分配和释放,他们的使用需要包含标准库文件

#include<stdlib.h>

实现内存分配的核释放的4个主要函数:

Void *malloc(size_t size);

Void free(void *ptr)

Void *calloc(size_t nmemb, size_t size) 与malloc不同的是,会把内容初始化为0;

Void *realloc(void* ptr, size_t size) 是malloc 和 free的结合

当ptr=NULL时,相当于malloc, 此时不初始化为0

当size = 0 时,相当于free

当size小于原来分配的大小,ptr不变,重合部分内存不变,多余部分释放

当size 大于原来分配的大小,ptr可能变化,

若原分配内存区域后面是未分配的空间,则不需要移动内存指针,即ptr不变,重合部分内存不变,多余部分为不确定数

若原分配内存区域后面为有足够空间,则需要移动内存指针,按照新内存大小,重新分配一块内存空间,将原有内存中的内容,复制到新的内存空间中,释放原有看内存空间。

 

参考文献:嵌入式Linux上的C语言编程实践 韩超,魏治宇 电子工业出版社

 

三:全局区(静态区static):

包含只读数据段,读写数据段,未初始化数据段。

四:文字常量区

五:程序代码区

 

六:比较

 

这是一个前辈写的,非常详细

  //main.cpp

  int a = 0; 全局初始化区

  char *p1; 全局未初始化区

  main()

  {

  int b; 栈

  char s[] = "abc"; 栈

  char *p2; 栈

  char *p3 = "123456"; 123456\0在常量区,p3在栈上。

  static int c =0; 全局(静态)初始化区

  p1 = (char *)malloc(10);

  p2 = (char *)malloc(20);

  }

  分配得来得10和20字节的区域就在堆区。

strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。

 

堆具有灵活性,何时分配,释放的逻辑完全由编程人员决定。但是存在风险,如1:开辟内存未及时释放,造成内存泄露,2:野指针的存在,内存已经释放,但该指针仍被使用,正确的做法是一旦该指针指向的内存一旦释放,就将该指针赋值为NULL。在使用某指针时,首先判断该指针是否是NULL

3:非法释放指针,未给指针分配内存就释放。

总之又果必有因,只有作为malloc(),calloc()或realloc()返回值的指针,才可以被free()释放和被realloc()处理。

 

栈的存取速度比较快。但使用不够灵活。

 

这些都是辩证的,需要编程人员合理的选择利用堆栈,从使用的角度,一般来说,栈内存更适用于容量较小的单个变量(如C语言的基本变量类型,较小的结构体和数组),而堆内存适用于开辟较大的块内存。

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值