1、开发时, 如果我们需要用到多个数据的话,首先我们想到的是使用数组,但是因为数组的长度在定义完后是固定的所以往往不够灵活。这时我们可以根据需要存储的数据类型先定义一个指针变量,例如:int *p,然后根据实际需求使用malloc函数分配空间。
2、malloc 函数:
#include <stdlib.h>
void *malloc(size_t size);
malloc 函数向系统申请size个字节的内存空间并返回一个指针,这个指针指向被分配的内存空间的首地址,并且申请的内存空间是在“堆”上的,堆上的空间是需要手动申请、手动释放的,否则会造成内存泄漏的问题。
如果我们需要存储10个int类型的数据
int *p;
p = (int *)malloc(10*sizeof(int));
注意:分配的空间为10*sizeof(int),因为malloc申请分配的空间是以字节为单位的
#include <stdio.h>
#include <stdlib.h>
int main()
{
//定义指针变量
int *p;
//通过指针变量p操作一块空间,可以存储4个int类型的数据
//向系统申请4*sizeof(int)字节的内存空间
//在堆上申请了4*sizeof(int)字节的内存空间
p = (int*)malloc(4*sizeof(int));
//打印p的值:申请到的堆上的内存空间的首地址(指针p指向申请到的堆上空间)
printf("p:%p\n",p);
//通过指针变量p来操作申请到的堆空间
p[0] = 100;
p[1] = 200;
*(p+2) = 300;
*(p+3) = 400;
return 0;
}
注意:栈空间:自动分配 自动回收
堆空间:手动申请 手动释放
3、内存释放:free函数
#include <stdlib.h>
void free(void *ptr);
功能:释放ptr所指向的内存空间
注意:
(1)free函数不会修改指针变量的值,但是执行完毕后指针所指向的原来的那块地址空间中的内容是不确定的。
(2)最重要的是:告诉系统这块内存空间可以给别人使用了。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int mian(int argc,char *argv[])
{
char *p;
//malloc分配的空间是在堆上的,需要手动释放
p = (char *)malloc(10);
strcpy(p,"hello");
printf("p所指向的空间的内容:%s\n",p);
//结果是hello
printf("p所指向的空间的内容:%s\n",p);
//将p所指向的地址空间首地址打印出来(就是将指针变量p的值打印出来)
printf("p的值:%p\n",p);
free(p);
//下面打印语句的结果不是hello了
printf("p所指向的空间的内容:%s\n",p);
strcpy(p,"world");
//下面打印语句的结果是world
printf("p所指向的空间的内容:%s\n",p);
return 0;
}
free函数调用完以后的使用技巧
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int mian(int argc,char *argv[])
{
char *p;
//malloc分配的空间是在堆上的,需要手动释放
p = (char *)malloc(10);
strcpy(p,"hello");
//释放申请的内容
free(p);
p = NULL;
return 0;
}
4、如果之前分配的空间不够了怎么办?
可以使用realloc函数:
#include <stdlib.h>
void *realloc(void *ptr,size_t size);
功能:
在堆上分配一块size所指定的新的内存空间,空间大小单位为字节,并且还会将ptr所指向的 空间中的内容拷贝到新的内存空间中,最后返回新的内存空间的额首地址。
#include <stdlib.h>
#include <stdio.h>
int main()
{
char *p;
p = (char *)malloc(10);
strcpy(p, "hello"); //向分配的空间中拷贝字符串
printf("p所指向空间的首地址: %p\n", p);
printf("p所指向空间的内容: %s\n", p);
p = (char *)realloc(p, 20); //重新分配新的空间
printf("p所指向新的空间的首地址: %p\n", p);
printf("p所指向新的空间的内容: %s\n", p);
//注意:分配的新的空间的首地址有可能有之前分配的空间首地址一样,也有可能不一样
strcat(p, " world"); //追加字符串
printf("p所指向新的空间的内容: %s\n", p);
return 0;
}