内存分配(Day-9)
来源:互联网 发布:c语言接口的定义 编辑:程序博客网 时间:2024/06/08 02:03
计算机内存划分为5个区:栈区 堆区 静态区 常量区 代码区
1. 5大区:
栈区:
1.1. 函数的参数或者是局部变量存储在栈区
1.2. 局部变量:在函数 分支 循环的{}中定义的变量
1.3. 栈区内存的管理方式:由系统负责分配和回收
1.4. 定义变量时分配,函数执行结束后系统回收
1.5. 内存被系统回收后,原来存储的数据没有被清空,只是标记回收
1.6. 栈区存储的特点:先进后出 后进先出
1.7. 入栈:定义变量在栈区分配存储空间,出栈: 回收内存
1.8. 栈顶:后放进去的数据在栈顶 栈底:栈区内存起始的位置
|_______栈顶_________| 高
|____________________| |
|____________________| |
|_______栈底_________| 低常量区(文字常量区):
2.1. 常量区的内存管理:由系统分配和回收(程序结束运行时被回收)
2.2. 常量区的数据只能被读取,不能被修改全局变量:
3.1. 使用关键字static修饰的变量 以及在函数外定义的变量(全局变量或者静态变量)
3.2. 静态区的内存管理:由系统分配和回收(程序运行结束回收)
3.3. 静态区的变量只能初始化一次,在编译时进行初始化
3.4. 静态区的变量没有设置初始值时,默认值为:0代码区:函数运行时存储的区域
4.1. 代码区的内存管理机制:系统负责分配和回收
4.2. 回收:程序运行结束后堆区:
5.1. 堆区的内存管理:开发人员负责分配与回收
5.2. 回收:程序员自行回收
5.3. void *malloc(size_t):指定分配的存储空间的大小(字节数), 将分配的存储空间的起始地址返回
堆内存是使用地址操作,地址存储在对应的指针变量中
void *malloc(<#size_t#>)
/*
void *:无类型指针
malloc = memory (内存) allocation(分配)
size 表示分配多大的存储空间,单位是字节
*/
malloc返回的是地址,需要用指针获取
// 1. 动态分配int的空间 然后赋值 int *p = malloc(sizeof(int)); *p = 89;// 2. 在堆中存储4个整型数 int *p = malloc(sizeof(int) * 4); for (int i = 0; i < 4; i++) { *(p+i) = i; } for (int i = 0; i < 4; i++) { printf("%d ",*(p+i)); }//3. 在堆中存储一个人名 char *p = malloc(sizeof(char) * 20); strcpy(p, "zhangsanfeng") ; printf("%s ", p);//4. 随机产生10个30--45之间的随机数,存储在堆内存中 int *p = malloc(sizeof(int) * 10); for (int i = 0; i < 10; i++) { *(p+i) = arc4random() % 16 + 30; } for (int i = 0; i < 10; i++) { printf("%d ",*(p+i)); }
例1:
有一个字符串,里面包含数字,提取出里面的数字,然后动态分配内存存储
char p[] = "BJS150936"; int len = (int)strlen(p); int count = 0; for (int i = 0; i < len; i++) { if (p[i] >= '0' && p[i] <= '9') { count++; } } printf("%d ",count); int *pi = malloc(sizeof(int) * count); int j = 0; for (int i = 0; i < len; i++) { if (p[i] >= '0' && p[i] <= '9') { pi[j] = p[i] - '0';//将字符转换为数字 j++; } } for (int i = 0; i < count; i++) { printf("%d ", pi[i]); }
5.4. free() 函数:内存释放是标记删除
内存泄露:分配空间之后,没有回收
野指针:指向了一个已经被回收的内存
malloc函数分配完空间之后,一定要进行释放,否则产生内存泄露的问题
int *p = malloc(sizeof(int)); *p = 20; free(p); printf("%d", *p); // <---野指针:指向了一个被回收的内存 // 刚释放的内存没有被使用,所以暂时没有报错 // 打印结果是:20
5.5 其他的内存分配函数:
// 1. void *calloc(size_t, size_t); 第一个是申请几个 第二个是数据类型的字节/*calloc = clear allocation 1. 在堆内存分配n个size字节的空间,并返回地址 2. 会将分配的存储空间中原有的数据清空*///1.1 在堆中存储5个整型数,范围是15--35之间的随机数 int *p = calloc(5, sizeof(int)); for (int i = 0; i < 5; i++) { p[i] = arc4random() % 21 + 15; } for (int i = 0; i < 5; i++) { printf("%d ", p[i]); } free(p); // 死也不能忘记释放内存呀!!!!!! malloc calloc都需要程序员释放的呀// 2. void *realloc(void *, size_t); 按给定的地址及给定的大小重新分配 释放新的内存, 旧的不用 int *p = malloc(sizeof(10)); int *ps = realloc(p, 20); printf("p = %p, ps = %p\n", p, ps); /* 结果:p = 0x10020dd40, ps = 0x10020ae70 给p重新分配20个字节,地址0x10020dd40不够20个, 所以重新开辟了一块空间,分配20个给p。 不用释放p,需要释放后来分配的空间---ps ~~~~~~~~~~ */
5.6. 内存操作函数:
**初始化内存**// 1.void *memset(void *s, int, c size_t n); 从s指向的地址开始,将n个字节初始化为int c int *p = malloc(sizeof(int)); memset(p, 0, sizeof(int)); ** 内存拷贝 ** // 2.void *memcpy(void *dest, const void *source, size_t n);从source开始,拷贝n个字节到dest char str1[] = "bjS140936"; char str2[] = "15"; memcpy(str1, "BJ", 2); memcpy(str1+3, str2, 2); printf("%s ", str1); // 结果:BJS150936 ** 内存比较 ** /* 3. int memcmp(const void *buf1, const void *buf2, size_t count);比较 buf1和buf2指向的内存是否相同,比较count个字节*/// 例3.1 定义两个整型指针,分别⽤malloc、calloc对其分配空间保存3个元素,malloc分配的空间⽤用memset清零,随机对数组进⾏行赋值随机范围1-3,赋值后⽤用memcmp⽐比较两个数组。如果相同打印Good!否则打印Failed... int *p1= malloc(sizeof(int) * 3); memset(p1, 0, sizeof(int) * 3); int *p2 = calloc(3, sizeof(int)); for (int i = 0; i < 3; i++) { *(p1 + i) = arc4random() % 3 + 1; *(p2 + i) = arc4random() % 3 + 1; } int a = memcmp(p1, p2, sizeof(int) * 3); printf("%d ",a); // a<0 也就是Failed
- 内存分配(Day-9)
- 9、动态内存分配
- 037day(动态内存分配和内联函数,重载函数,函数参数缺省值的学习)
- 动态内存分配 (转载)
- 内存分配问题(转)
- 内存地址分配 (转载)
- Java内存分配(一)
- Java内存分配(二)
- Java内存分配(三)
- Windows内存分配(转)
- 内存分配原理(转)
- 内存分配管理(一)
- C 内存分配(转载)
- C 内存分配(转载)
- 动态内存分配(详解)
- 动态内存分配(详解)
- 内存分配(第八章)
- 动态内存分配(2)
- 对象库编程VS描述性编程
- System进程的启动流程第一部分
- SAP ABAP编程 弹窗操作函数
- Activity生命周期
- Ubuntu下Qt安装全过程解答
- 内存分配(Day-9)
- VS2015调试功能初探
- CUDA简介
- Linux Core Dump
- lintcode-带最小值操作的栈-12
- Unix 文件系统的核心目录总结
- 传智播客助力一带一路IT人才培养
- 怎么样查看局域网IP地址是否被占用?
- 认识QTP自动化测试工具