内容简介:void main(){//静态内存分配创建数组,数组的大小是固定的//int a[10];
int a[1024];
二、 C语言 内存分配
1、栈区(stack)
- windows下,栈内存分配2M(确定的常数),超出了限制,提示 stack overflow 错误;
- 栈区中内存自动分配,自动释放
2、堆区(heap)
-
程序员手动分配内存,手动释放内存,占有操作系统80%的内存,通过malloc进行内存分配
`
//在堆内存分配40M内存
//malloc参数是字节
//malloc 返回值是 void,是任意类型的指针
p = malloc(1024 1024 10 * sizeof(int));//释放分配的内存
free(p);
- calloc - realloc 重新分配内存 - 创建一个数组,动态指定数组的大小(在程序运行过程中,可以随意的开辟指定大小的内存,以供使用;相对于 Java 中的集合)
void main(){
//静态内存分配创建数组,数组的大小是固定的
//int a[10];
int len; printf("输入数组的长度:"); scanf("%d",&len); //开辟内存 int* p = malloc(len * sizeof(int)); //p是数组的首地址 //给数组元素赋值(使用这一块刚刚开辟出来的内存区域) int i = 0; for(;i < len; i++){ p[i] = rand() % 100; printf("%d,%#x\n",p[i],&p[i]); } //扩大刚刚分配的内存空间 printf("重新输入数组的长度:"); scanf("%d",&len); //参数说明 //1:原来的内存的指针 //2:内存扩大之后的总大小 int* p2 = realloc(p,sizeof(int) * len); //重新赋值 i = 0; for(;i < len; i++){ p2[i] = rand() % 200; printf("%d,%#x\n",p2[i],&p2[i]); } //手动释放内存 if(p != NULL){ free(p); p = NULL; } if(p2 != NULL){ free(p2); p2 = NULL; } getchar();
}
输入结果为(参考):
输入数组的长度:6
41,0x202330
67,0x202334
34,0x202338
0,0x20233c
69,0x202340
24,0x202344
`
3、全局区或静态区
4、字符常量
5、程序代码区
三、静态内存分配与动态内存分配的区别
静态内存分配,分配内存大小是固定的;容易出现以下问题:
- 很容易超出栈内存的最大值
- 为了防止内存不够用会开辟更多的内存,容易浪费
动态内存分配,在程序运行过程中,动态指定需要使用的内存大小,手动释放,释放之后这些内存还可以被重新使用;容易出现以下问题:
- 缩小,缩小的那部分数据会丢失
- 扩大(连续的),如果当前内存段后面有需要的内存空间,直接扩展这段内存空间,realloc返回原指针;如果当前内存段后面的空闲字节不够,那么久使用堆中的第一个能够满足这一要求的内存块,将目前的数据复制到新的位置,并将原来的数据释放,返回新的内存地址;如果申请失败,返回NULL,原来的指针任然有效。
四、内存分配的几个注意细节
- 不能多次释放
- 释放完之后,给指针置为NULL
- 内存泄漏(p重载赋值之后,在free,并没有真正释放内存)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 操作系统学习笔记-11:内存分配(一):连续分配
- 操作系统学习笔记-12:内存分配(二):非连续分配
- 图解 Go 内存管理器的内存分配策略
- Go:内存管理分配
- Allocations分析内存分配
- 内存分配与回收策略
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。