c语言--内存学习总结



变量在内存中的形式


1.定义

作用域 :变量声明后时,只有在一定区域内才能被访问
存储期:程序中变量的储存终止时间
链接: 链接属性是为了说明在不同文件中出现的相同标识符应该如何处理

  • 作用域(分类)
    • 块作用域
    • 函数作用域
    • 文件作用域

ps:作用域只与变量定义的位置有关,在哪里定义,作用域就是哪里!


2.关键字

  • auto(void):自动(作用域结束,存储期结束,无链接)
  • register:寄存器(不在内存中存储,无法获取地址,但响应快)
  • extern:外部变量
  • static:
    • 静态变量(程序结束,存储期结束)
    • 隐藏(表1)
    • 默认初始化为0

ps1: 关键字不会影响作用域,只是对存储期和链接的修改
ps2: register---系统根据实际情况,选择是否将变量放入寄存器中
ps3: extern---在文件中使用外部链接变量,要extern声明,否则会被隐藏
ps4: extern---它的作用是表示变量或者函数的定义在别的文件中,而不是创建外部变量
ps5: static---不用担心自己定义的变量,是否会与其它文件中的同名
ps6: 当重名出现时,内层会掩盖外层变量,但不会覆盖(只是另外创建一个新的同名变量)

作用域效果
文件内部链接,其他文件无法调用
主函数内部链接,与系统自动设置相同
自定义函数无链接,主要目的是静态变量

表1.static隐藏功效(链接)的几种情况


3.存储类型

存储类别存储期作用域链接
自动自动
寄存器自动
静态外部链接静态文件外部
静态外部链接静态文件内部
静态无链接静态

分配内存


1.malloc()和free()

 
  1. if(scanf("%d",&max)!=1)
  2. {
  3. puts("Number not correctly entered---bye.");
  4. exit(EXIT_FAILURE);
  5. }
  6. double* ptd;
  7. ptd=(double *)malloc(max*sizeof(double));
  8. long* new;
  9. new=(long *)calloc(max,sizeof(long));
  10. if(ptd == NULL)
  11. {
  12. puts("Memory allocation failed.Goodbye.");
  13. exit(EXIT_FAILURE);//程序意外退出
  14. }
  15. free(ptd);
  16. free(new);

ps1: malloc() free() exit()都在stdlib.h的头文件中
ps2: malloc()返回值是指针,成功为首地址,失败为空指针
ps3: free()能清除malloc()或calloc()分配的内存
ps4: malloc()生成的数组,依然可以进行数组操作
ps5: 使用malloc()后,记得用free()释放动态内存,防止内存泄漏
ps6: 一般exit(EXIT_SUCCESS)表示程序寿终正寝,exit(EXIT_FAILURE)表示死于非命。
ps7: 同一块内存多次使用,对于需要短暂使用内存的部分很使用
ps8: 使用malloc时,有可能无法成功分配内存,一定要判断地址是否为空指针

malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。如果无法获得符合要求的内存块,malloc函数会返回NULL指针,因此在调用malloc动态申请内存块时,一定要进行返回值的判断。


2.储存类别与内存分配

存储类别内存分配
静态储存程序声明建立,程序结束消失
自动储存储存在栈中,按顺序加入相反顺序销毁
动态分配储存不连续, 使用相对较慢

3.程序运行期间的几种内存

1、栈区:由编译器自动分配 存放函数的参数值,局部变量的值等,操作方式类似于数据结构中的栈。
2、堆区:一般由程序员分配释放,若程序员不释放,程序结束时 可能 有系统收回。它与数据结构中的堆是两回事。分配方式类似于链表。
3、全局区(静态区):全局变量和静态变量是存储放在一块的,初始化的全局变量和静态变量在一个区域,未初始化的在相邻的另一个区域。
程序结束后由系统释放。
4、文字常量区:常量字符串就存放在这里。程序结束后有系统自动释放。
5、程序代码区:存放函数体的二进制代码。


4.函数名与内存

  • 程序中的函数名、变量名、标号都是一个代号,对应一个地址,就如同指针一样。编译程序在程序中发现你使用函数名时,就会相应替换使用函数名的地方用这个地址*
  • 编译后在汇编里面调用的就是纯粹内存地址了之间的调用和我们定义的变量名函数名就没关系了
  • 源代码编译后,函数本身成为一个以入口地址开始的连续内容(操作数据段的代码、只有代码,没有数据),函数名将被彻底抹掉。不过有时候你写dll会发现函数名仍然以某种形式保留下来,但是那些名字只是为了提供给程序加载器识别用的。到了执行状态凡是用到的函数,对应的名称都会被替换成代码地址。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值