[C语言底子]13.动态内存管理

[复制链接]
发表于 2025-10-15 00:55:54 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
1. 动态内存分配

  1. int val = 20;//在栈空间上开辟四个字节  
  2. char arr[10] = {0};//在栈空间上开辟10个字节的连续空间
复制代码

  • 空间开辟巨细是固定的。
  • 数组在阐明时,必须指定命组长度,所需内存在编译时分配。
2. 动态内存函数的先容

2.1 malloc

  1. void* malloc (size_t size);
复制代码
动态内存开辟函数:


  • 向内存申请一块一连可用的空间,返回指向这块空间的指针。
  • 开辟乐成,则返回一个指向开辟好空间的指针。
  • 开辟失败,则返回一个NULL指针,因此malloc的返回值肯定要做查抄。
    返回范例是 void*,malloc函数并不知道开辟空间的范例,详细在使用的时间使用者自己来决定。
    malloc申请到空间后,直接返回空间起始地点,不会初始化空间。
  1. #include <stdlib.h>
  2. int main() {
  3.         int* p = (int*)malloc(40);
  4.         if (p == NULL) {//检测malloc返回指针
  5.                 perror("malloc");
  6.                 return 1;
  7.         }
  8.         int i = 0;
  9.         for (i = 0; i < 10; i++) {
  10.                 printf("%d\n", *(p + i));
  11.         }
  12.         free(p);//释放空间
  13.         p = NULL;//p变成野指针,要置为空指针
  14.         return 0;
  15. }
复制代码
2.2 free

  1. void free (void* ptr);
复制代码
malloc申请内存空间,不会主动开释内存,必要free开释。步调退出时会还给体系。
如果参数 ptr 是NULL指针,则函数什么事都不做。
2.3 calloc

  1. void* calloc (size_t num, size_t size);
复制代码


  • 为 num 个巨细 为 size 的元素开辟一块空间,而且把空间的每个字节初始化为0。
  • calloc 会在返回地点前,把申请的空间的每个字节初始化为全0。
  • malloc申请到空间后,直接返回空间起始地点,不会初始化空间。
  1. #include <stdlib.h>
  2. int main() {
  3.         int* p = (int*)calloc(10, sizeof(int));
  4.         if (p == NULL) {//检测calloc返回指针
  5.                 perror("calloc");
  6.                 return 1;
  7.         }
  8.         int i = 0;
  9.         for (i = 0; i < 10; i++) {
  10.                 printf("%d ", p[i]);
  11.         }
  12.         free(p);//释放空间
  13.         p = NULL;//p置为空指针
  14.         return 0;
  15. }
复制代码
0 0 0 0 0 0 0 0 0 0
2.4 realloc

  1. void* realloc (void* ptr, size_t size);
复制代码


  • realloc 可以调解动态开辟内存巨细,返回调解后的内存位置
  • ptr:必要调解的内存地点;size:调解后的新巨细
    调解空间巨细的环境:
    1.原有空间后有空间
  • 原有内存后直接追加空间,原来空间的数据稳定
    2.原有空间后没空间
  • 在堆空间上另找一个符合巨细的一连空间来使用
  • 会将原来内存中的数据移动到新的空间
  • 开释旧空间,返回新空间内存地点
  1. int main() {
  2.         int* p = (int*)malloc(40);
  3.         if (p == NULL) {
  4.                 perror("calloc");
  5.                 return 1;
  6.         }
  7.         //初始化
  8.         int i = 0;
  9.         for (i = 0; i < 10; i++) {
  10.                 p[i] = i + 1;
  11.         }
  12.         //增加空间
  13.         int* ptr = (int*)realloc(p, 80);
  14.         if (ptr != NULL) {
  15.                 p = ptr;//如果扩展失败了,p被置为NULL,故不能直接使用p接受新指针,否则会内存泄漏
  16.         }
  17.         else {
  18.                 perror("realloc");
  19.                 return 1;
  20.         }
  21.         //打印数据
  22.         for (i = 0; i < 20; i++) {
  23.                 printf("%d ", p[i]);
  24.         }
  25.         free(p);//释放空间
  26.         p = NULL;//p置为空指针
  27.         return 0;
  28. }
复制代码
1 2 3 4 5 6 7 8 9 10 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451
3. 动态内存错误

3.1 NULL指针解引用

  1. void test()  {  
  2.         int *p = (int *)malloc(INT_MAX/4);  
  3.         *p = 20;//如果p的值是NULL,就会有问题  
  4.         free(p);  
  5. }
复制代码
3.2 动态开辟空间越界访问

  1. int main() {
  2.         int* p = (int*)malloc(40);//10个整形
  3.         if (NULL == p){
  4.                 perror("malloc");
  5.                 return 1;
  6.         }
  7.         int i = 0;
  8.         for (i = 0; i <= 20; i++){
  9.                 p[i] = i;//越界访问
  10.         }
  11.         free(p);
  12.         p = NULL;
  13.         return 0;
  14. }
复制代码
3.3 非动态开辟内存使用free开释

  1. int main() {
  2.         int a = 10;
  3.         int* p = &a;
  4.         printf("%d\n", *p);
  5.         //a不是动态开辟的
  6.         free(p);
  7.         p = NULL;
  8.         return 0;
  9. }
复制代码
3.4 free开释动态开辟内存的一部门

  1. int main() {
  2.         int* p = (int*)malloc(40);
  3.         if (NULL == p){
  4.                 perror("malloc");
  5.                 return 1;
  6.         }
  7.         int i = 0;
  8.         for (i = 0; i < 5; i++) {
  9.                 *p = i;
  10.                 p++;
  11.         }
  12.         free(p);//p已经不指向起始位置
  13.         p = NULL;
  14.         return 0;
  15. }
复制代码
3.5 同一块动态内存多次开释

  1. int main() {
  2.         int* p = (int*)malloc(40);
  3.         if (NULL == p) {
  4.                 perror("malloc");
  5.                 return 1;
  6.         }
  7.         free(p);
  8.         free(p);//p多次释放
  9.         p = NULL;
  10.         return 0;
  11. }
复制代码
每次开释完p置空
  1. free(p);
  2. p = NULL;
复制代码
3.6 动态开辟内存未开释(内存走漏)

  1. void test(){
  2.         int* p = (int*)malloc(100);
  3.         if (NULL != p){
  4.                 *p = 20;
  5.         }
  6. }
  7. int main(){
  8.         test();
  9.         while (1);
  10. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表