一、指针与malloc
1、指针与动态内存申请
数组长度固定是因为其定义的整型、浮点型、字符型变量、数组变量都在栈空间内中,而栈空间的大小在编译时是确定的。如果内存大小不确定,那么就要使用堆空间了
//指针与动态内存申请
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h> //使用malloc
#include<string.h> //使用strcpy
int main()
{
int size; //代表要申请多大字节的空间
char* p;
scanf("%d", &size); //输入要申请的空间大小
//malloc返回的是起始地址
//malloc返回的void*代表无类型指针
p = (char*)malloc(size);
strcpy(p,"malloc success"); //strcpy可以直接往空间中放
puts(p);
free(p); //malloc申请的空间用完之后需要释放内存
//释放的地址必须是最初malloc返回给我们的地址
printf("free success\n"); //打印释放成功
return 0;
}
二、栈和堆空间的区别
1、栈
栈是计算机系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈、出栈都有专门的指令执行,这就决定了栈的效率比较高。
2、堆
堆则是C/C++函数库提供的数据结构,它的机制是很复杂,例如:为了分配一块内存,库函数会按照一定的算法(具体的算法请参考关于数据结构、操作系统的书籍)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能由于内存碎片太多),那么就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后返回。显然,堆的效率要比栈低得多。 (这段了解即可)
堆是动态的
栈空间由系统自动管理,而堆空间的申请和释放需要自行管理,所以在具体例子中需要通过 free 函数释放堆空间。free 函数的头文件及格式为
三、堆空间和栈空间的差异
//堆是heap
//栈是stack
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h> //使用malloc
#include<string.h> //使用strcpy
char* print_stack()
{
char c[100] = "I am print_stack function";
char* p;
p = c;
puts(p);
return p;
}
char* print_malloc()
{
char* p = (char*)malloc(100);
strcpy(p, "I am print malloc function");
puts(p);
return p;
}
int main()
{
char* p;
p = print_stack(); //函数调用完后,操作系统就会释放这个栈空间,返回这个栈的起始地址
puts(p); //打印的是乱码,因为这个栈的起始地址是之前的print_stack函数的起始地址
p = print_malloc();
puts(p); //不会打印乱码,因为堆空间在整个进程中一直有效,不因为函数结束而消亡
free(p); //只有free之后堆空间才会释放
return 0;
}