我们之前学过的存储类别有一个共同之处:在确定用哪种存储类别后,根据已制定好的内存管理规则,将自动选择其作用域和存储期。然而,还有更灵活的选择,即利用库函数分配和和管理内存。
首先,回顾一下内存分配,所有的程序都必须预留足够的内存来存储程序使用的数据,这些内存中有些是自动分配的,有的显式指定分配一定数量的内存。静态数据在程序载入内存时分配,而自动数据在程序执行时分配,并在程序离开该块是销毁。
int x;
char str[]="Hello,Word"];
int arr[10]={
0};
C语言还可以让我们在程序运行是分配更多的内存。主要的工具是malloc()函数,该函数接受一个参数:所需的内存字节数。malloc()函数会找到合适的空闲内存块,这样的内存是匿名的,不会为其赋名。但他会返回动态分配内存块的首地址。因此,可以把该地址赋给一个指针变量,通过该指针来访问这块内存。如今的malloc()的返回值是一个指向void的指针,该类型指针相当于一个”通用指针“,通常其会被强制转换匹配的类型。
int *arr=nullptr;
arr=(int*)malloc(sizeof(int)*10);
指针arr被声明指向了一个int类型,而不是指向一个内含10个int类型的块,这与我们的数组名相同,我们可以向使用数组一样来使用他。
现在,我们有3种方法创建数组的方法。
1.声明数组时,用常量表达式表示数组的维度,用数组名访问数组的元素。可以用静态内存或自动内存创建这种数组。
2.声明变长数组(C99),用变量表达式表示数组的维度,用数组名访问数组的元素。具有这种特性的数组只能在自动内存中创建。
3.声明一个指针,调用malloc(),将其返回值赋给指针,使用指针访问数组的元素。该
指针可以是静态的或自动的。
使用第2种和第3种方法可以创建动态数组(dynamic array)。这种数组和普通数组不同,
可以在程序运行时选择数组的大小和分配内存。例如
int arr[n];//C99之前,不允许n为变量
int *arr1=(int*)malloc(sizeof(int)*n);//C99之前也允许
但是使用库函数来申请空间,并不是每次都能申请成功的,申请失败时他会返回一个空指针,这种情况下我们一般使用exit()结束程序。
free()函数及其重要性
通常,malloc()要与free()配套便用。free ()函数的参数是之前malloc()返回的地址,该函数释放之前malloc() 分配的内存。因此,动态分配内存的存储期从调用malloc()分配内存到调用free()释放内存为止。设想 malloc()和free()管理着一个内存池。每次调用malloc()分配内存给程序使用,每次调用free()把内存归还内存池中&#