先理论来一波:
C 库函数 void *malloc(size_t size) 分配所需的内存空间,并返回一个指向它的指针。
void *malloc(size_t size)
size – 内存块的大小,以字节为单位。
该函数返回一个指针 ,指向已分配大小的内存。如果请求失败,则返回 NULL。
----------------------------------------------------------分割线----------------------------------------------------------------------
我知道malloc在堆上,然后栈是系统管的,堆是用户管的。
使用栈就象我们去饭馆里吃饭(或吃快餐),只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。
但到底啥时候用malloc还是没搞清楚。
其实具体还是看情况的,但万变不离其宗,就是:
当无法知道内存具体的位置时,想要绑定真正的内存空间,就要用到malloc()函数。
但感觉还是太抽象,举例子说明更好一点:
//例1
#include "stdio.h"
#include "malloc.h" //malloc()函数被包含在malloc.h里面
int main(void)
{
char*a=NULL; //声明一个指向a的char*类型的指针
a=(char*)malloc(100*sizeof(char)); //使用malloc分配内存的首地址,然后赋值给a
if(!a) //如果malloc失败,可以得到一些log
{
perror("malloc"); //申请失败了,返回 -1
return -1;
}
sprintf(a,"%s","HelloWorld\n"); //将"HelloWorld\n"写入a指向的地址
printf("%s\n",a); //输出用户输入的数据
free(a); //释放掉使用的内存地址
return 0;
}
不然的话,你也可以将 “HelloWorld” 赋值到一个数组或结构体里面啥的,反正最后让指针a 有地方可指向就好了。这里一开始,如果指针不malloc一下,直接将字符串赋给指针a,就会出现段错误,原因是a不知道指向哪,而且 “HelloWorld” 也不知道放在哪,因为没空间放它。
看下面扯上结构体的简单例子:
//例2
#include "stdio.h"
#include <string.h>
#include "malloc.h" //malloc()函数被包含在malloc.h里面
struct son
{
char hi[12];
int year;
};
struct father
{
struct son *son1;
} father1;
int main(void)
{
//方法一,结构体指针嵌套时(暂无指针结构体一说的概念),自己malloc
father1.son1 = (struct son *)malloc(sizeof(struct son)); //使用malloc分配内存的首地址,然后赋值给father1.son1->hi
if (!father1.son1) //如果malloc失败,可以得到一些log
{
perror("malloc error"); //申请失败了,返回 -1
return -1;
}
strcpy(father1.son1->hi, "Hello");
father1.son1->year = 2022;
printf("method one:%s,%d\n", father1.son1->hi, father1.son1->year);
free(father1.son1); //释放掉使用的内存地址
father1.son1 = NULL; //注意,释放掉了malloc空间,但结构体指针依然存在,仍需要指向NULL;
//方法二,结构体指针嵌套时,找个有地址空间的来进行数据传输
struct son son2; //先声明一个结构体
strcpy(son2.hi, "Hello"); //结构体赋值
son2.year = 2022;
father1.son1 = &son2; //son1直接指向son2
printf("method two:%s,%d\n", father1.son1->hi, father1.son1->year);
return 0;
}
例2的输出结果:
method one:Hello,2022
method two:Hello,2022