动态内存管理(二)

简介: 动态内存管理

4.经典笔试题


4.1 题目一


void Memory(char* ptr)
{
  ptr = (char*)malloc(20);
}
void test()
{
  char* p = NULL;
  Memory(p);
  strcpy(p, "crush");
  printf(p);
}
int main()
{
  test();
  return 0;
}


0fc3d974f6b54ad217d05819ba4e56f4_d913589276ce4173aa6ad2ef1d58a0c0.png

1.当程序开辟动态内存退出函数Memory时,临时变量ptr被销毁,开辟的动态内存没有被释放,再也找不到,由此造成内存泄漏。 2.p是空指针,strcpy执行时,会对p解引用然后会崩溃的


4.2 题目二


char* Memory()
{
  char ch[] = "hello crush";
  return ch;
}
void test()
{
  char* p = NULL;
  p = Memory();
  printf(p);
}
int main()
{
  test();
  return 0;
}


当程序离开函数 Memory时,数组 char ch[]就会被销毁,所以指针 p接收到一块不明内容的地址,打印结果就是未知的,也就是野指针。


d5a4b45c8130af8eca3a4c59da3d0963_c62b48a1b87b4e4cb5bbb5894b8bad8e.png


4.3 题目三


void Memory(char** ptr, int num)
{
  *ptr = (char*)malloc(num);
}
void test()
{
  char* p = NULL;
  Memory(&p, 20);
  strcpy(p, "crush");
  printf(p);
}
int main()
{
  test();
  return 0;
}


3018eaa2eff3de71682b58c2815eb1e9_91773a8d71bb420bbfedcca9d46d5698.png


唯一的缺点就是没有对开辟的动态内存进行释放,和将指针置为空指针。


9aae90a9611e1105c4ab77daca9ed836_0f70979dc23f4f38b93968d67b0cf63b.png


4.4 题目四


void test()
{
  char* p = (char*)malloc(20);
  strcpy(p, "crush");
  free(p);
  if (p != NULL)
  {
  strcpy(p, "crush");
  printf(p);
  }
}
int main()
{
  test();
  return 0;
}


8009fbfb87b870711737f6fc79f39385_bf2e24cefbe742f79982627c6feba159.png


典型野指针,动态开辟的内存被释放之后,指针 p只能记得地址,但不能继续使用,因此变成野指针。


5.柔性数组


C99标准中,结构体中最后一个元素允许是未知大小的数组,称作柔性数组


struct M
{
  int i;
  int arr[];//柔性数组
};

5.1柔性数组的特点


1. 结构体中的柔性数组成员前面必须至少一个其他成员
 2. sizeof返回结构体大小时,不包括柔性数组的内存
 3. 包含柔性数组的结构体需要用malloc()函数进行内存的动态分配
 并且分配的内存必须大于结构体的大小,以满足柔性数组对内存的需求


struct M
{
  int i;
  int arr[];//柔性数组
};
int main()
{
  printf("%d\n", sizeof(struct M));
  return 0;
}

image.png


5.2柔性数组的使用

#include<stdio.h>
#include<string.h>
#include<errno.h>
struct M
{
  int n;
  int arr[];//柔性数组
};
int main()
{
  //柔性数组的使用
  struct M* p = (struct M*)malloc(sizeof(struct M) + 20);
  if (p == NULL)
  {
  printf("%s\n", strerror(errno));
  return;
  }
  p->n = 0;
  int i = 0;
  for (i = 0; i < 5; i++)
  {
  p->arr[i] = i;
  }
  for (i = 0; i < 5; i++)
  {
  printf("%d ", p->arr[i]);
  }
  printf("\n");
  //扩容
  struct M* ptr = (struct M*)realloc(p, 40);
  if (ptr != NULL)
  {
  p = ptr;
  }
  //释放内存
  free(p);
  p = NULL;
  return 0;
}



78113f521b98908f0c8806f197b9dd07_66cd08e446844590b041dc57ab099869.png

e424c0f24f17830a34d5109c739a2a2d_64083aa63d2340aeb3206761353087e2.png


类似柔性数组的使用方法


#include<stdio.h>
#include<string.h>
#include<errno.h>
struct M
{
  int n;
  int* arr;
};
int main()
{
    //动态内存开辟
  struct M* p = (struct M*)malloc(sizeof(struct M));
  if (p == NULL)
  {
  printf("%s\n", strerror(errno));
  return;
  }
  p->n = 0;
  p->arr = (int*)malloc(20);
  int i = 0;
  for (i = 0; i < 5; i++)
  {
  p->arr[i] = i;
  }
  for (i = 0; i < 5; i++)
  {
  printf("%d ", p->arr[i]);
  }
  //扩容
  int* ptr = (int*)realloc(p->arr, 40);
  if (ptr != NULL)
  {
  p->arr = ptr;
  }
  //释放
  free(p->arr);
  free(p);
  p = NULL;
  return 0;
}


1415397e54229aae30ceb2fa0255fbbd_118832a7ead64de38d816e2760df5256.png

300bd97112cb33e13d1849d708968a91_f249410db7c24501a18c86546aba5f7e.png


5.3柔性数组的优点


上面两种方法都可以实现相同的目的-柔性数组的使用

相比之下,还是第一种方法更好一些


优点1:方便内存释放

第一种方法只需要释放一次内存即可,而第二种方法需要释放两次


优点2:访问速度更快

连续的内存有利于提高访问速度,也有利于减少内存碎片


目录
相关文章
|
人工智能
【AI绘画】ControlNet 之 Reference only 锁定面部跑图
【AI绘画】ControlNet 之 Reference only 锁定面部跑图
1546 0
|
人工智能 物联网
如何将Together AI上基于Qwen2-7B训练的模型部署到ModelScope平台
如何将Together AI上基于Qwen2-7B训练的模型部署到ModelScope平台
366 10
|
Web App开发 移动开发 前端开发
html5 canvas五彩碎纸屑飘落动画特效
h5 canvas飘落纸片动画是一款实现五彩纸屑飘落的背景动画特效,基于canvas绘制的空中飘落的纸屑片动画特效,适用于网页动态背景效果代码。简单使用,欢迎下载!代码适用浏览器:搜狗、360、FireFox(建议)、Chrome、Safari、Opera、傲游、世界之窗,是一款不错的的特效插件,希望大家喜欢!
258 5
|
Shell Python BI
targetcli内核态操作实战
工作中一旦遇到内核态的东西感觉操作非常困难,并且各种的权限的限制导致的操作非常困难,最终往往都是重启了事。比如进程出现了僵尸D状态,活着出现内核态数据残留,例如sysfs数据残留等
689 2
|
机器学习/深度学习 存储 搜索推荐
Elasticsearch与深度学习框架的集成案例研究
Elasticsearch 是一个强大的搜索引擎和分析引擎,广泛应用于实时数据处理和全文搜索。深度学习框架如 TensorFlow 和 PyTorch 则被用来构建复杂的机器学习模型。本文将探讨如何将 Elasticsearch 与这些深度学习框架集成,以实现高级的数据分析和预测任务。
342 0
|
消息中间件 SQL Kafka
实时计算 Flink版操作报错合集之遇到报错:javax.management.InstanceAlreadyExistsException,该如何处理
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
缓存
idea配置JRebel
idea配置JRebel
221 0
|
消息中间件 存储 Java
【MQ 快速入门】介绍、分类、组成、优缺点、测试点
【MQ 快速入门】介绍、分类、组成、优缺点、测试点
【MQ 快速入门】介绍、分类、组成、优缺点、测试点
|
编解码 Linux 开发工具
全志D1s在macOS操作系统环境下载程序
D1s是全志针对智能解码市场推出的高性价比AIoT芯片。它使用64bit RISC-V架构的阿里平头哥C906处理器,内置了64M DDR2,支持Linux系统,同时集成了大量自研的音视频编解码相关IP,可以支持H.265,、H.264、MPEG-1/2/4、JPEG等全格式视频解码,支持ADC/DAC/I2S/PCM/DMIC/OWA等多种音频接口,可以广泛应用于智能家居面板、智能商显、工业控制、车载等产品。
668 0
全志D1s在macOS操作系统环境下载程序

热门文章

最新文章