
本文共 3143 字,大约阅读时间需要 10 分钟。
在声明数组时,必须用一个编译时常量指定数组的长度,但由于数组所需的内存空间取决于输入数据的大小,这在某些情况下是不确定的。例如,一个用于计算学生等级和平均分的程序可能需要存储一个班级所有学生的数据,但不同班级的学生数量可能有所不同。在这种情况下,使用动态内存分配是一种更好的选择。
首先,malloc
函数用于向内存申请一块连续可用的空间,并返回指向这块空间的指针。其函数原型为:
void* malloc (size_t size);
malloc
函数的使用注意事项如下:
malloc
后必须进行检查。malloc
函数并不了解空间的具体类型,这需要在使用时由开发者自行决定。size
为 0,malloc
的行为在编译器间可能存在差异,通常的情况下,这种行为是未定义的。接着,free
函数用于释放动态分配的内存。它的函数原型为:
void free (void* ptr);
free
函数的使用注意事项:
ptr
指针所指向的空间,释放之后 ptr
仍然指向释放的空间,因此在释放后建议将 ptr
设为 NULL。ptr
不指向动态分配的内存,free
的行为是未定义的。ptr
是一个空指针(即 NULL),函数将无需进行任何操作。以下是一个使用 malloc
和 free
的示例代码:
#include#include int main() { int* ptr = NULL; ptr = (int*)malloc(num * sizeof(int)); // 确保 num 是一个正整数 if (ptr != NULL) { int i = 0; for (i = 0; i < num; i++) { *(ptr + i) = 0; } } free(ptr); ptr = NULL; return 0;}
接下来,calloc
函数也用于分配内存,其函数原型为:
void* calloc(size_t num_elements, size_t element_size);
calloc
函数的主要特点是,它们不仅为 num_elements
个元素分配内存,还将每个元素的内容初始化为 0。它与 malloc
之间的主要区别在于前者会在返回指针之前将空间初始化为 0。一种常见使用方式是:
#include#include int main() { int* p = (int*)calloc(10, sizeof(int)); if (p != NULL) { // 使用空间 } free(p); p = NULL;}
realloc
函数用于修改已分配的内存块的大小,其函数原型为:
void* realloc(void* ptr, size_t new_size);
realloc
函数的主要使用场景包括:
realloc
的使用也需要注意以下几点:
ptr
为 NULL,realloc
的行为与 malloc
相同,分配一块大小为 new_size
的空间。realloc
会将内容复制到新分配的空间中,原空间会被释放。此时,内容的完整性需要由开发者自行保证。以下是一个使用 realloc
的示例代码:
#include#include int main() { int* p = NULL; p = (int*)malloc(100); int* ptr = (int*)realloc(p, 1000); if (ptr != NULL) { p = ptr; } // 业务处理 free(p);}
在实际开发过程中,动态内存分配容易出现一些常见错误,开发者需要特别注意以下几点:
ptr
在使用 malloc
或 calloc
之后不是 NULL。free
。free
只能用于释放完整的动态内存块。free
。最后,关于柔性数组的使用,C99标准中允许在结构体中使用一个未知大小的数组成员(即柔性数组成员)。这种成员的组织方式有如下特点:
sizeof
操作符返回的结构体大小不包括柔性数组占用的空间。malloc
函数进行动态内存分配,并且分配的空间大小必须大于结构体的大小,以便柔性数组成员有足够的空间进行保存。以下是一个柔性数组的示例代码:
#include#include typedef struct FlexArray { int n; char c; int arr[];} FlexArray;int main() { FlexArray* pF = (FlexArray*)malloc(sizeof(FlexArray) + 10 * sizeof(int)); pF->n = 100; int i = 0; for (i = 0; i < 10; i++) { pF->arr[i] = i; } free(pF); pF = NULL;}
在实际开发中,可以选择使用柔性数组成员来灵活存储未知长度的数据,或者手动分配内存,像这样:
#include#include typedef struct S { int n; int* arr;} s;int main() { s* ps = (s*)malloc(sizeof(s)); ps->arr = (int*)malloc(sizeof(int) * 10); int i = 0; for (i = 0; i < 10; i++) { ps->arr[i] = i; } free(ps->arr); ps->arr = NULL; free(ps); ps = NULL;}
两种方式的功能是相同的,但使用柔性数组的方式具有以下优势:
发表评论
最新留言
关于作者
