malloc动态开辟内存空间
01——malloc动态开辟内存空间函数:
通常定义数组的时候就把内存地址定好了,比如:
ind data[] = {1,2,3,4,5};
char cdata[6] = {‘h’,’e’,’l’,’l’,’o’};
有一种需求:我不希望一开始就耗费这么大的空间,我想按需求开辟内存空间,引入动态开辟字符串malloc函数。
malloc函数就是我们在堆上面动态的开辟字符串,它跟以前我们数组占用的使用的内存空间是不一样的,以前我们数组都是在栈区,那么堆是malloc对应的内存空间。
malloc函数原型:void *malloc(size_t size)
c库函数:void *malloc(size_t size)分配所需的内存空间,并返回一个指向它的指针。
*我们之前写过一个例子,对这个p进行赋值的时候会产生一个段错误,p是一个野指针,对野指针赋值我们会看到犯错,如果不会犯错程序中end会执行,你会看到end根本就不会执行,p没有具体的指向哪个内存空间。
断错误
我们使用malloc函数开辟一个内存空间用p来承接它:
编译我们看到:想要使用malloc函数需要包含库文件#include <stdlib.h>
此时p就不是野指针了,p就有了具体的内存指向:内存地址:0x0000000000727E80
02——strcpy拷贝函数应用:
我们可以开辟一个内存空间,当然也可以开辟多个内存空间:,这里开辟了12个内存空间,仍然用p来承接。这个时候就需要往里面放数据了,于是引入一个函数(strcpy字符串拷贝函数)。
函数原型:char *strcpy(char* dest, const char *src);
字符串拷贝函数strcpy(拷贝到哪里去,从哪里拷贝);
程序写完之后发现有一个警告,提示如果要使用strcpy这个函数就必须包含头文件#include <string.h>
现在看到可以了,输出demo结果:chenlichen这个字符串
——???————————但是现在有一个问题???
刚开始p指向的是你开辟的一个内存空间,但是你又开辟了12字节内存空间也让p指向了它,此时p就会和之前开辟的那一块内存空间断开,并指向新开辟的12字节内存空间;此时那一块和p断开的内存就成了悬挂无用的内存了,已经找不到这个地址了,空闲在这了。像这种空闲在这的内存我们通常需要通过free将其释放。
因为malloc它在堆上面开辟内存空间,数组和普通的变量是在栈开辟内存空间,在函数调用结束以后它会清理栈里面的数组(回收内存),那堆只有到程序结束以后内存才会释放(有一个风险,如果你是一个死循环,不断地malloc,有可能会耗尽你计算机上堆的内存资源),所以需要通过free将其释放掉!!!
03——free函数应用:
free:c库函数void free(void *ptr);
作用:释放之前调用calloc、malloc和realloc所分配的内存空间,释放无用内存,防止内存泄漏,防止悬挂指针(悬挂指针是野指针的一种)。
尽量不要悬挂指针!!!
free释放掉无用内存后,一般让p = NULL;
04——realloc扩容函数应用:
比如说现在有这么多的数据需要放到内存空间中,而上面malloc只开辟了12个字节的内存空间,如果这么多数据需要放到里面的话是不行的,会发生越界,程序崩溃!!!
这个时候就可以使用realloc扩容函数来解决!
realloc函数原型:void *realloc(void *ptr, size_t size);
字符串扩容函数realloc(原本扩容地址,要继续增大多少);
作用:尝试重新调整之前调用malloc和calloc所分配的ptr所指向的内存块大小。
注意:扩容前和扩容和的地址一样的!!!
05——memset函数应用:
清理内存空间memset函数应用
memset函数原型:void *memset(void *str,int c,size_t n)
void *memset(新开辟的内存地址,要初始化的内容,内存大小);
把malloc申请的12个字节的内存空间,全部清理成\0
综合demo: