🍬目录
🥙一、前言
🌮二、动态内存分配
🥙一、前言
C语言的数据结构通常是固定大小的,一旦程序完成编译,数组元素的数量就固定了。因为在编写程序时强制选择了大小,为了扩大数据库的容易量,可以增加数组的大小,并重新编译程序,但这种数组也会再次填。为了解决以上困绕,C语言支持动态内存分配即在程序执行期间分配内存单元的能力,利用动态内存分配,可以设计根据需要选择扩大或缩小的数据结构。
🌮二、动态内存分配
内存分配函数,要使动态地分配存储空间,要调用三种内存分配函数的一种,这些函数都声明在<stdilb.h>文件中,这些函数能申请的内存空间属于堆区。
🍬:内存分配函数介绍
malloc函数————分配内存块,但是不对内存块进行初始化
calloc函数————分配内存块,并且对内存块进行清零。
realloc函数————调整先前分配的内存块大小。 free函数————释放内存块。
🍰malloc函数
函数原型:
void* malloc (size_t size);
分配一个字节级的内存块,返回指向块开头的指针。新分配的内存块的内容未初始化,保留不确定的值。返回值取决于特定的库实现(它可能是也可能不是空指针)内存块的大小(以字节为单位),size_t是无符号整型。成功时,指向函数分配的内存块的指针。此指针的类型始终为,可以强制转换为所需类型的数据指针,以便可取消引用。如果函数无法分配请求的内存块,则返回空指针。
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* ptr = (int*)malloc(20);//申请20字节的内存空间
if (ptr == NULL)//判断是否申请成功
{
perror("calloc");
return 1;
}
return 0;
}
malloc函数并不会初始化这段内存空间。
🍬:calloc函数
函数原型:
void* calloc (size_t num, size_t size);
calloc函数为个元素的数组分配内存空间,其中每个元素的长度都是1个字节。如果要求的空间无效,那么此函数返回空指针。在分配了内存之后,calloc函数会通过把所有位设置为0的方式进行初始化。例并且保证所有整数初始均为零。
#include<stdio.h>
#include<stdlib.h>
int main()
{
char* ptr1 = (char*)calloc(30,sizeof(char));//申请30个char元素的内存空间
if (ptr1 == NULL)//判断是否申请成功
{
perror("calloc");
return 1;
}
return 0;
}
🍬:realloc函数
函数原型:
void* realloc (void* ptr, size_t size);
一旦为数组分配完内存,稍后可能会发现数组过大或过小。realloc函数可以有效调整数组的大小使它更适合需要;当调用realloc数时,ptr必须指向先前通malloc、calloc或realloc的语用获得的内存块。size表示内存块的新尺寸,新尺寸可能会大于或小于原有尺寸。虽然realloc函数不要ptr指向正在用作数组的内存,但实际上通常是这样的,要确定传递给realloc函数的指针来自于先前malloc、alloc成=eal1oc的语用。如果不是这样的指针,程序可能会行为异常。
C标准列出了几条关于realoc函数的规则:
🌮:如果realloc函数不能按要求扩大内存块,那么它会返回空指针,并且在原有的内存块中的数据不会发生改变。
🍰:如果realloc函数被满用对以空指针作为第一个实际参数,那么它的行为就将像mallce函数一样。
🍬:如果realloc函数被调用时以0作为第二个实际参数,那么它会释放掉内存块。
C标准没有确切地指明realloc函教的工作原理。尽管如此,我们仍然希望它非常有效。在要求减少内存块大小时,realloc函数应该“在原先的内存块上”直接进行缩减,而不需要移动存储在内存块中的数据。同理,扩大内存块时也不应该对其进行移动。如果无法扩大内存块(因为内存块后边的字节已经用于其他目的),realloc的数会在别处分配新的内存块,然后把旧块中的内容复制到新块中。
realloc函数返回,请一定要对指向内存块的所有指针进行更新,因为realloc函数可能会使内存块移动到了其他地方。
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* ptr = (int*)malloc(20);//申请20字节的内存空间
if (ptr == NULL)//判断是否申请成功
{
perror("calloc");
return 1;
}
int* p = (int*)realloc(ptr, 40);
if (p == NULL)//判断扩展是否申请成功
{
perror("calloc");
return 1;
}
ptr=p;
return 0;
}
情况1:
情况2:
🍬:当扩展内存块时,realloc函数不会对添加进内存块的字节进行初始化。
🍬:free函数
void free (void* ptr);
free函数的实际参数必须是先前由内在分配数返回的指针。(参数也可以是空指针,此时free调用不起作用如果参数是指向其他对象(比如变量或数组元素)的指针,可能会导致未定义的行为。