C语言的内存管理
来源:互联网 发布:淘宝开店策划方案 编辑:程序博客网 时间:2024/04/25 11:31
一 变量的类型:
1. 全局变量:代码块之外的变量,全局变量一般是在.c中定义的,在.h用extern关键字声明的(定义只能是一次,声明是可以多次),如果其他.c文件想用就可以调用这个.h就行。还有另外几种方法来实现全局变量在多个.c文件共享。
2. 静态变量:static关键字修饰的变量,静态变量有2种,一种是代码块之外的静态变量,这个是变量的只是本文件可用,代码块之内的静态变量,只能被代码块内所使用
3.局部变量:代码块内部的变量,没有任何的修饰符,实际这些变量的隐藏的修饰符是auto
变量的一个很重要的性质作用域与内存的管理有很大的关系,作用域就是这个变量的生命周期、存在时间。
二 函数:函数默认都是全局的,当然也可以用static变量修饰,那么这个函数成了仅本文件有效。
三 内存管理:
每一个应用程序都把所占用的内存分为了几个区域:下面就是分配示意图
#include <stdio.h>#include <string.h>#include <stdlib.h>int a = 10;//已经初始化的全局变量,数据段 int h;//未初始化的全局变量,bss段 static int b = 15;//全局static变量,数据段 int test(int x, int y);int main(void){int i = 0;//局部变量,栈 printf("&a = %p, a = %d, &b = %p, b = %d, &i = %p, i = %d, &h = %p, h = %d\n", &a, a, &b, b, &i, i, &h, h);int c = 1;printf("&c = %p, c = %d\n", &c, c);char *s ="hello";//s 存放栈,hello常量,数据段,所以s指向的内存在数据段 char *p = (char*)malloc(10);//堆 printf("&p = %p, p = %d, p = %s\n", &p, p, p);if (p != NULL){strcpy(p,s);}printf("&p = %p, p = %d, %s\n", &p, p, p);printf("c = %p, %s\n", s, s);i = test(a,c);printf("&i = %p, i = %d\n", &i, i);i = test(a,c);printf("&i = %p, i = %d\n", &i, i);if (p != NULL)//下面这段比较容易被忽视,但 { free(p); printf("&p = %p, p = %d, %s\n", &p, p, p); p = NULL; printf("&p = %p, p = %d, %s\n", &p, p, p);}return 0;}int test(int x, int y){static int d = 0;//数据段 printf("&d = %p, d = %d\n", &d, d);int e = 2;d += (x -y -e);return d;}
这些内存区分别都存了那些数据呢
1.代码段:存放cpu要执行的指令,通常都是只读,防止被修改。
2.数据段:已经初始化的全局变量,常量,静态变量。
3.bss段:未初始化的全局变量。
4.栈:是由编译器自动分配和释放的,存放的是一些局部变量和函数的参数。地址是向下生长的。每当函数被调用的时候,会把函数的返回地址和一些调用信息存放在栈区,再为函数的临时变量和参数在栈区申请内存。函数返回时,这些临时变量和参数的内存就会别销毁。
5堆:程序员自行分配和释放,不自行释放就会造成一些意想不到的bug,地址是向上生长的。
分了这么多区,编译器是基于什么呢,代码都是顺序执行,通过递归和跳转会重复执行一些代码,因为一些代码块会被重复使用,所以代码块里面申请的变量都放在栈里面,全局变量和静态变量一般在整个程序运行时期都要被访问。这样就可以节约内存。
- C语言的内存管理
- C语言的内存管理
- C语言的内存管理
- C语言的内存管理
- C语言的内存管理
- C语言的内存管理
- C语言的内存管理
- C语言的内存管理
- C语言的内存管理
- C语言的内存管理
- c语言的内存管理
- C语言的内存管理
- C语言内存管理
- C语言内存管理
- C语言内存管理
- C语言内存管理
- C语言-内存管理
- C语言内存管理
- windows下python安装scipy库的方法
- mysql 全文索引
- 微信小程序 wxml 中一些属性的使用
- selenium之 chromedriver与chrome版本映射表(更新至v2.27)
- Android访问权限Permission
- C语言的内存管理
- 注入的两种方式
- 网台开发笔记
- jquery 日期插件
- Attempt to insert non-property list object - 芒果iOS
- 大小端
- 学了一个递归
- 常用的32个算法
- EasyPlayer RTSP/RTMP/HTTP/HLS全功能播放器