在程序运行的过程中,常常需要动态的分配和撤销内存空间,今天让我一起学习如何动态的分配内存空间,了解栈和堆区别,以及内存呢在什么情况下会丢失。
一、内存组织的方式
我们在完成程序的编写后,需要把程序装载到计算机的内核或者半导体中,在运行。程序被组织成了一下4 个逻辑段。
- 可执行代码
- 静态数据。可执行代码和静态数据存储的固定位置。
- 动态数据(堆)
- 栈。局部数据对象,函数的参数,函数调用和被调函数是被所有同时运行的程序共享的操作系统资源,也可以是程序独占的局部资源。
二.栈与堆的概念
堆用来存放动态分配的内存空间,而栈用来存放局部变量,函数的参数,以及调用函数和被调函数。
1.堆
在c 程序中用于动态分配和释放的内存块称为自由空间,也称之为堆。用malloc和free函数来从堆中动态的分配和注释内存。
给出一下实例
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* pInt;//定义了一个整型的指针
pInt = (int*)malloc(sizeof(int));//分配内存
*pInt = 10;//使用分配内存
printf("the number is :%d\n",*pInt);//输出显示数值
free(pInt);//释放内存
return 0;
}
注意这里一定要引入头文件include<stdlib.h>否则不能开辟空间会报错
2.栈
当程序调用函数和声明局部变量时,系统会自动分配内存。栈是一个后进先出的结构,对于这部分内容来说有一个函数栈帧的创建和销毁,不在这里赘述。
三.动态管理
- malloc函数
- calloc函数
- realloc函数
- free函数
1.malloc函数
malloc函数的函数原型如下
void*malloc(unsigned int size);
首先包含都文件stdlib.h它的作用是在内存中动态的分配一块size大小空间 ,malloc函数会返回一个指针,指向分配的内存空间,若出现错误返回NULL(注意,使用malloc函数是分配在堆空间中,不是在栈。因此在使用完后一定要释放掉,释放用的是free函数,若不释放可能导致系统崩
溃。)
int main()
{
int* iIntMalloc = (int*)malloc(sizeof(int));
*iIntMalloc = 100;
printf("%d\n", *iIntMalloc);
free(iIntMalloc);//释放内存
printf("%d\n", *iIntMalloc);
return 0;
}
我们在调试时候看到在申请了空间后,用free释放了。
int*pInt;
pInt=(int*)malloc(sizeof(int));
首先利用定义的指针pInt来保存分配的内存地址,使用malloc时需要指定内存大小(size)这时候调用sizeof函数可以得到指定的类型大小空间。malloc成功分配空间后会得到一个指针,因为是一个int类型的指针,所有返回的指针也是int型,要进行强制转换,最后将返回的指针赋给pInt,就可以保存动态分配的空间地址。
2.calloc函数
calloc函数的原型如下
void*calloc(unsigned n,unsiged size);
使用该函数要包含头文件stdlib.h。其功能是分配n个长度为size的连续内存空间数组。calloc会返回一个数组。calloc函数会返回一个指针,该指针指向动态分配的连续内存空间地址,当分配错误时候返回NULL。
int*pArray;//定义指针
pArry=(int*)calloc(3,sizeof(int));//分配内存数组
上面代码中pArray为一个整型指针 ,使用calloc函数分配内存数组,在参数中第一个参数表示分配数组中元素的个数,第二个参数表示元素的类型,最后将返回的指针赋予pArray指针变量,pArray指向的该数组的首地址。
#include<stdlib.h>
int main()
{
int* pArray;
int i;
pArray = (int*)calloc(3, sizeof(int));
for (i = 1; i < 4; i++)
{
*pArray = 10 * i;
printf("NO%d is:%d\n", i, *pArray);
pArray++;
}
return 0;
}
3.realloc函数
void* realloc(void* ptr, size_t size);
该函数的功能改变ptr指针指向的空间大小为size.设定的size大小可以是任意的,也就是说可以比以前大,也可以比以前小。返回值是一个新的指针,如改变一个实型空间为整型空间。
include<stdlib.h>
int main()
{
double* fDouble;
int* iInt;
fDouble = (double*)malloc(sizeof(double));
printf("%d\n",sizeof(*fDouble));
iInt = realloc(fDouble, sizeof(int));
printf("%d\n", sizeof(*iInt ));
return 0;
}
先使用malloc来分配实型大小空间,然后通过sizeof输出内存空间大小,最后用realloc来获得新的内存空间大小。
4.free函数
free函数是释放指针ptr指向的内存区域,使部分内存可以被其他变量使用。ptr是最近一次malloc或者calloc函数返回的值,free无返回值。
free(pInt);
这里引用malloc的函数代码
4.总结
学习了内存分配的原理,知道了动态分配有4种函数,适当的free空间在一定程度上体现了程序的优美风格和健壮性。