如果是没头脑和不高兴需要你存储他们的成绩,定义两个变量足以;学习数组之后,我们甚至可以存下一整个班的成绩;但是如果我不知道这个班有多少人,又或者我要存储更多信息呢?为了避免数据溢出或者内存浪费,动态内存分配是一个不错的选择。
C语言中,常见的动态内存分配方法有malloc函数、calloc函数和realloc函数,本文先介绍malloc函数,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址
malloc的有关概念
通过这段代码让我们简单对malloc函数有一个基本的概念,它的作用是动态内存分配一块空间存储并且输出一个一维数组。
#include <stdio.h> #include <stdlib.h> int main() { int n; scanf("%d",&n); //输入 int *str1=(int*)malloc(n*sizeof(int)); //动态内存分配 if(str1==NULL) { return 1; } //判断是否开辟成功 for(int i=0;i<n;i++) { scanf("%d",&str1[i]); } //输入数组中的值 for(int i=0;i<n;i++) { printf("%d",str1[i]); } //输出数组 free(str1); //释放内存 return 0; } ?
malloc的头文件
该函数包含在头文件<stdlib.h>中,这意味着我们使用该函数时代码需要包括该文件。
malloc的函数参数
void*malloc(size_t size);
该参数类型是size_t,就是我们所说的无符号整形,它表示要开辟的内存块大小,并且以字节为单位计算,函数通过该参数来知道需要动态开辟多少个字节的空间;
malloc的返回值(可用于检测是否分配成功)
函数的返回值类型是void*(【注】无类型指针(void*)和空指针(NULL)并非一个概念;无类型指针是一种通用指针类型,可以指向任何类型的数据,在C语言中可以通过强制类型转换将其转换为其他类型的指针;空指针是一个特殊的指针值,用于表示指针未指向任何有效的内存地址,在C语言中可以将其赋给任何类型指针以表示无效指针);
if(str1==NULL)
{
return 1;
}
malloc()函数在运行结束时会返回给主函数动态开辟好的空间块首地址,如果开辟失败则返回一个NULL指针,因此malloc函数的返回值用于检测是否分配成功。
malloc的使用形式
参考格式
数据类型 *指针变量 = (数据类型 *)malloc(要分配的内存大小);
引用代码中的int *str1=(int*)malloc(n*sizeof(int)); 就是对应这部分,实际使用时使用int *str1=(int*)malloc(sizeof(int));形式函数依然可以使用,具体原因在下一篇进阶版中会做详细介绍;
malloc的注意事项
数据溢出问题
你不会真的以为动态内存分配就不存在数据溢出了吧~不会吧~不会吧~
一旦使用malloc()函数分配了动态内存空间,分配后的空间大小是固定的,不会在程序运行过程中发生改变,在代码int *str1=(int*)malloc(n*sizeof(int));中,n*sizeof(int)确定了分配的内存大小。malloc()函数根据这个大小分配一块连续的内存空间并且返回一个指向该指针的空间str1,直到你使用free()函数释放该内存空间或者重新分配新的内存空间;
为了避免这种问题,建议在申请内存空间时,根据实际需求合理设置内存大小,确保有足够内存可用。
free函数释放内存
free函数可用于释放之前通过malloc()函数、realloc()函数和calloc()函数分配的动态内存空间。其函数原型:
void free(void*ptr)
其中ptr是要释放的内存空间指针,在释放内存之前要确保不再使用该空间,否则会导致未定义的行为,比如下面这段代码
#include <stdio.h> #include <stdlib.h> int main() { int* nums = (int*)malloc(5 * sizeof(int)); if (nums == NULL) { printf("内存分配失败 "); return -1; } // 使用内存空间... free(nums); return 0; }
在上述代码中,首先调用malloc函数分配了一个大小为5*sizeof(int)的内存空间,并且将地址赋值给指针nums,然后检查nums是否为NULL,如果是,分配失败,返回-1;接下来使用内存空间;最后释放并且将nums指向的内存空间释放。