内存分配
1、在实际工作中,如果我们需要存储多个数据很多同学首先想到的是使用数组,但是因为数组的长度在定义完后是固定的所以往往不够灵活。
2、我们可以根据需要存储的数据类型先定义一个指针变量,例如:int *p; 然后根据实际需求使用malloc函数分配空间。
3、malloc函数:
#include <stdlib.h>
void *malloc(size_t size);
功能:malloc 函数像系统申请size个字节的内存空间,并且返回一个指针,这个指针指向被分配的内存空间的首地址,并且申请的内存空间是在“堆”上的。堆上的空间是需要手动申请,手动释放的!!否则就会造成内存泄漏。
int *p;
//假如我们需要存储10个int类型的数据
p = (int *)malloc(10*sizeof(int));
注意:分配的空间为 10*sizeof(int), 因为malloc申请分配的空间是以字节为单位的。
int *p;
//通过指针变量p操作一块空间,可以存储4个int数据
//向系统申请 4*sizeof(int)字节的内存空间
p = (int *)malloc(4*sizeof(int)); //在堆上申请了4*sizeof(int)字节的内存空间
//p的值:申请到的堆上的内存空间的首地址 (指针p指向申请到的堆上的空间)
printf("p: %p\n", p);
//通过指针变量p 来操作申请到的堆空间
p[0] = 100;
p[1] = 200;
*(p+2) = 300;
*(p+3) = 400;
4、内存释放:free函数
#include <stdlib.h>
void free(void *ptr);
功能:释放ptr所指向的内存空间
注意:
free函数并不会修改指针变量的值!但是free执行完成以后指针所指向的原来的那块地址空间中
的内容是不确定的!!
问题:
释放空间到底做了什么事情呢?
最重要的是:告诉系统这块内存空间可以给别人使用了!!!
5、如果之前分配的空间不够了怎么办呢?
我们可以使用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;
}
6、思考一种情景,char *dest, *src; 通过一个函数将src所指向的地址空间中的内容拷贝到dest所指
向的地址空间中,但是假设在调用函数前我们并不知道src的长度,这个时候我们需要将函数的形参设
计为 二级指针!
我们可以使用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;
}
6、思考一种情景,char *dest, *src; 通过一个函数将src所指向的地址空间中的内容拷贝到dest所指
向的地址空间中,但是假设在调用函数前我们并不知道src的长度,这个时候我们需要将函数的形参设
计为 二级指针!
评论区