为什么要使用动态内存:
1.按需分配内存,用完就释放,不浪费
2.被调用函数之外需要使用被调用函数内部的指针对应的地址空间
3.突破栈区的限制,给程序分配更多的内存
1.按需分配内存,用完就释放,不浪费
使用的编译器为:VC++ 2010
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void) {
//表示10个农民伯伯薪水的数组(日薪)
int farmer[10] = {160,230,100,650,490,330,550,454,780,300};
int num = 0;//农民伯伯数量
int *salary = NULL;
printf("请输入雇佣农民伯伯的数量:");
scanf_s("%d", &num);
salary = new int[num];//分配num个整型变量的动态内存
//第一种 逐个赋值
//for(int i=0; i<sizeof(farmer)/sizeof(int); i++) {
//salary[i] = farmer[i];
//}
//第二种 内存拷贝
memcpy(salary, farmer, sizeof(farmer));
for(int i=sizeof(farmer)/sizeof(int); i<num; i++) {
salary[i] = 50000;
}
for(int i=0; i<num; i++) {
printf("第%d个能民的薪水:%d\n", i+1, salary[i]);
}
delete[] salary;//释放动态内存
system("pause");
return 0;
}
2.被调用函数之外需要使用被调用函数内部的指针对应的地址空间
第一种 通过函数返回一个动态内存起始地址
#include<stdio.h>
#include<stdlib.h>
//第一种
int *demo1(int count) {
int *ap = NULL;
//分配以ap为起始地址的count个int类型的动态内存
ap = (int *)malloc(sizeof(int) * count);//c语言中分配动态内存的函数malloc
for(int i=0; i<count; i++) {
*(ap+i) = 100 + i;
}
for(int i=0; i<count; i++) {
printf("*(ap+%d) = %d\n", i, *(ap+i));
}
return ap;
}
int main(void) {
int *pointer = NULL;
int count = 0;
scanf_s("%d", &count);
//第一种 通过函数返回一个动态内存起始地址
pointer = demo1(count);
for(int i=0; i<count; i++) {
printf("*(pointer+%d) = %d\n", i, *(pointer+i));
}
//用完之后,释放动态内存
free(pointer);//c语言中释放内存的函数
system("pause");
return 0;
}
注意:被调用函数之外需要使用被调用函数内部的指针对应的地址空间,返回的不可以是临时变量的地址,详情请参考我的另一篇博客《函数返回指针时,不能返回临时变量的地址,会出问题》
第二种 通过二级指针接收一级指针的地址,并对一级指针的内容进行操作,从而分配动态内存
#include<stdio.h>
#include<stdlib.h>
//第二种
void demo2(int **ap, int count) {
*ap = NULL;
//分配以地址*ap为起始地址的count个int类型的动态内存
*ap = (int *)malloc(sizeof(int) *count);
for(int i=0; i<count; i++) {
*(*ap+i) = 100 + i;
}
}
int main(void) {
int *pointer = NULL;
int count = 0;
scanf_s("%d", &count);
//第二种 直接传递一级指针的地址,通过二级指针对其进行分配动态内存的地址
demo2(&pointer, count);
for(int i=0; i<count; i++) {
printf("*(pointer+%d) = %d\n", i, *(pointer+i));
}
//用完之后,释放动态内存
free(pointer);//c语言中释放内存的函数
system("pause");
return 0;
}
3.突破栈区的限制,给程序分配更多的内存
在开发中,每个开发人员都想在栈区占用更多的资源,但是却是狼多肉少,栈空间并不大.
栈区的空间大小是有限制的,windows 上一般是 1M - 2M.
如果使用堆的话,64 位 windows 10 系统的限制是 2G.
单位换算:(B可以省略,写成1T,1G,1M,1K也可以)
1TB=1024GB
1GB=1024MB
1MB=1024KB
1KB=1024Byte(字节Byte简称B)=1024B=1024bytes
1B(B是Byte的简称)=1Byte(字节)=8bit(位)
#include<stdio.h>
#include<stdlib.h>
void demo3() {
int a1[102400 * 2];//100Kb*2*4 = 800Kb
printf("This is a demo.\n");
}
int main(void) {
printf("---start----\n");
demo3();
printf("---end----\n");
system("pause");
return 0;
}
在栈空间中,调用了800K
程序运行结果如下:
那么,乘于3呢?
#include<stdio.h>
#include<stdlib.h>
void demo3() {
//int a1[102400 * 2];//100Kb*2*4 = 800Kb
int a2[102400 * 3];//1.2M
printf("This is a demo.\n");
}
int main(void) {
printf("---start----\n");
demo3();
printf("---end----\n");
system("pause");
return 0;
}
在栈空间中,调用了1.2M
程序运行结果如下:
程序中断,栈空间溢出,再看看控制台:
程序已经不能执行printf(“This is a demo.\n”);这条语句
换成堆空间:
#include<stdio.h>
#include<stdlib.h>
void demo3() {
//int a1[102400 * 2];//100Kb*2*4 = 800Kb
//int a2[102400 * 3];//1.2M
int *a3 = NULL;
a3 = (int *)malloc(1024*1000*1000);//约为1G
a3[0] = 0;
printf("This is a demo.\n");
}
int main(void) {
printf("---start----\n");
demo3();
printf("---end----\n");
system("pause");
return 0;
}
程序运行结果如下:
那么,1.5G呢?
#include<stdio.h>
#include<stdlib.h>
void demo3() {
//int a1[102400 * 2];//100Kb*2*4 = 800Kb
//int a2[102400 * 3];//1.2M
int *a3 = NULL;
//a3 = (int *)malloc(1024*1000*1000);//约为1G
a3 = (int *)malloc((int)(1.5*1024*1000*1000));//约为1.5G
a3[0] = 0;
printf("This is a demo.\n");
}
int main(void) {
printf("---start----\n");
demo3();
printf("---end----\n");
system("pause");
return 0;
}
程序运行结果如下:
再来个1.9G,不写程序了,太多行了,直接上结果:
堆空间终于顶不住了!!!写入发生冲突,强行中断!
栈空间1.2M就不行了,而堆空间1.9G才强行中断。
因此,我们可以知道堆空间远大于栈空间!!!