------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
关于内存分区
计算机中的内存在用于编程时,被人为的进行了分区(Segment),分为:“栈区”(Stack)、“堆区”(Heap)、全局区(静态区,Static)
文字常量区和程序代码区。在学习变成的初期,主要涉及到的是栈区的内存,包括函数的参数值,局部变量的值等都被存在”栈区“。
这部分的内存,是由系统来帮助管理的,没有特殊情况的时候,是不需要对其进行特别处理的。
针对堆区的内存,一半由程序员进行分配和施放,使用堆内存的原因一般是”栈上内存比较小,不够用“、”系统管理内存的方式死板,不方便“
这两大类原因。对于堆上的内存,被程序员手动分配后,若不施放就很可能出现”内存泄漏“。很多企业级的应用,都因为内存泄漏而在”正常“
运转很长时间后,轰然”坍塌“。
关于全局变量和静态变量,他们的存储是在一块儿的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的
静态变量在相邻的另一块区域。程序结束后由系统施放;文字常量区是用于储存常量字符串的,程序结束后由系统施放;程序代码区用于存放函数的
二进制代码。
可变长度的数组
可变长度的数组,是在学习中第一个碰到的,需要使用动态内存的代码。
从数组的基本常识知道,int a[n]={}; 这样的初始化是不合法的,因为数组的长度必须固定,不能使用变量来创建数组。
那么如何使用一个变量来间接创建一个数组。
#include<stdio.h>
#include<malloc.h>
int main(){
int i,n;
scanf("%d",&n);
//请从下一行开始编写你的代码
int* arr = (int *)calloc(n, sizeof(int));
//以下代码对一个数组第一位进行了赋值
arr[0]=1;
//以下代码对长度为n的数组第二位开始做计算,并输出最后一个值的结果
for(i=1;i<n;i++){
arr[i]=arr[i-1]+i;
}
printf("%d",arr[n-1]);
return 0;
}
在这段代码中,一开始是不知道数组的具体大小的,由外界输入。在得到n之后呢,使用alloc函数从内存中划分出我们需要的空间,相当于创建了一个长度可自定义的数
组。
注意到,包含了一个名叫”malloc.h“的头文件。
这个头文件有三个最常见的三个函数。
malloc函数:
//函数原型
void *malloc(unsigned int size);
//调用形式
(类型说明符*)malloc(size)
功能:向系统申请size字节的堆空间。
返回值:所开辟中间首地址。
calloc函数:
//函数原型
void *calloc(unsigned int n, unsigned int size);
//调用形式
(类型说明符*)calloc(n,size)
功能:按类型申请n个size字节的堆空间,calloc函数与malloc函数的区别仅在于一次可以分配n块区域。
返回值:所开辟空间的首地址。
realloc函数:
//函数原型
void *realloc(void *p,unsigned int size);
功能:将p指向的堆空间变为size。
返回值:所开辟空间的首地址。
释放内存
有创建内存空间就有释放。
如何释放内存?还以刚才的数组为例。
#include<stdio.h>
#include<malloc.h>
int main(){
int i,n;
scanf("%d",&n);
int* arr=(int *)calloc(n,sizeof(int));
//以下代码对一个数组第一位进行了赋值
arr[0]=1;
//以下代码对一个长度为n的数组第二位开始依次做计算,并依次输出
for(i=1;i<n;i++){
arr[i]=arr[i-1]+i;
}
printf("%d",arr[n-1]);
//请在下一行释放内存空间
free(arr);
arr = NULL;
return 0;
}
在return 0;这句之前,使用free函数,它的作用是,释放arr数组指向的被分配的堆空间。
当然,最后为了安全起见,将叫做arr的指针数组指向一个叫NULL的位置,使之成为一个空指针,避免通过它又触碰到一个
已经被释放的内存位置。
搜索
复制