C 语言 内存管理
这章我们来学习下 C 语言中的动态内存管理里。 现在的编程语言,需要自己手动管理内存的已经不多了, C 语言是凤毛麟角中仅有的几个之一。
C 语言为分配和管理内存提供了几个函数。
这些函数的声明的头文件是 <stdlib.h>
函数 | 描述 |
---|---|
void *calloc(int n, int size) | 在内存中动态地分配 n 个长度为 size 的连续空间 并将每一个字节都初始化为 0。 结果是分配了 num*size 个字节长度的内存空间, 并且每个字节的值都是0 |
void free(void *address) | 释放 address 所指向的内存块 |
void *malloc(int num) | 在堆区分配一块指定大小的内存空间, 用来存放数据 这块内存空间在函数执行完成后不会被初始化 它们的值是未知的 |
void realloc(void addr, int nsize) | 该函数重新分配内存,把内存扩展到 nsize |
动态分配内存
我们在编程时,如果预先知道数组的大小,那么定义数组时就比较容易。 例如,需要一个存储人名的数组,它最多容纳 100 个字符,那么我们就可以像下面一样定义数组:
char people_name[100];
但是,如果预先不知道需要存储的文本长度,例如需要存储有关一个主题的详细描述。 那么,我们就需要定义一个指针,该指针指向未定义所学内存大小的字符,后续再根据需求来分配内存
/** * file: main.c * author: 简单教程(www.twle.cn) */ #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char people_name[100]; char *people_description; strcpy(people_name, "yufei"); /* 动态分配内存 */ people_description = malloc( 200 * sizeof(char) ); if( people_description == NULL ) { fprintf(stderr, "Error - unable to allocate required memory\n"); } else { strcpy( people_description, "yufei is the founder of www.twle.cn"); } printf("People Name = %s\n", people_name ); printf("People Description: %s\n", people_description ); }
编译和运行上面的代码,输出结果如下
$ gcc main.c && a.out People Name = yufei People Description: yufei is the founder of www.twle.cn
上面的程序,我们也可以使用 calloc() 代替 malloc
,如下所示
calloc(200, sizeof(char));
但
这是不被推荐的,虽然
calloc
也是内存函数 但很多人只认识malloc
, 而不知道calloc
是何物。
动态内存分配的优点
当动态分配内存时,我们有完全控制权,可以传递任何大小的值。 而那些预先定义了大小的数组,一旦定义则无法改变大小。
重新调整内存的大小和释放内存
当程序运行结束退出时,操作系统会自动释放所有分配给程序的内存,这是显而易见的。
但是,实践告诉我们,在不需要内存时,都应该调用函数 free() 来释放内存。
或者,可以通过调用函数 realloc() 来增加或减少已分配的内存块的大小。
让我们使用 realloc()
和 free()
函数来动态调整内存大小和释放他们
/** * file: main.c * author: 简单教程(www.twle.cn) */ #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char people_name[100]; char *people_description; strcpy(people_name, "yufei"); /* 动态分配内存 */ people_description = malloc( 40 * sizeof(char) ); if( people_description == NULL ) { fprintf(stderr, "Error - unable to allocate required memory\n"); } else { strcpy( people_description, "yufei is the founder of www.twle.cn"); } printf("People Name = %s\n", people_name ); printf("People Description: %s\n", people_description ); /* 假设您想要存储更大的描述信息 */ printf("\n内存调整过后\n"); people_description = realloc( people_description, 100 * sizeof(char) ); if( people_description == NULL ) { fprintf(stderr, "Error - unable to allocate required memory\n"); } else { strcat(people_description, "yufei is the founder of www.twle.cn, and he is a iter!"); } printf("Name = %s\n", people_name ); printf("Description: %s\n", people_description ); /* 使用 free() 函数释放内存 */ free(people_description); }
运行上面的程序,输出结果如下:
$ gcc main.c && a.out People Name = yufei People Description: yufei is the founder of www.twle.cn 内存调整过后 Name = yufei Description: yufei is the founder of www.twle.cnyufei is the founder of www.twle.cn, and he is a iter!
你可以尝试一下不重新分配额外的内存,那样,strcat() 函数会生成一个错误,因为存储 people_description 时可用的内存不足。