首页 > 系统相关 >c语音常见内存问题

c语音常见内存问题

时间:2024-10-09 10:49:04浏览次数:7  
标签:释放 动态内存 常见 越界 内存 语音 分配 指针

内存划分:

一、静态区
1、内存越界:
数据区内存越界主要指读写某一数据区内存(如全局或静态变量、数组或结构体等)时,超出该内存区域的合法范围
读越界和写越界
读越界表示读取不属于自己的数据,如读取的字节数多于分配给目标变量的字节数。若所读的内存地址无效,则程序立即崩溃;若所读的内存地址有效,则可读到随机的数据,导致不可预料的后果。
写越界亦称“缓冲区溢出”,所写入的数据对目标地址而言也是随机的,因此同样导致不可预料的后果。

写越界的主要原因有两种:1) memset/memcpy/memmove等内存覆写调用;2) 数组下标超出范围。
解决方法:
头尾校验

修改只读数据区内容会引发段错误

关键字volatile用于修饰易变的变量,告诉编译器该变量值可能会在任意时刻被意外地改变,因此不要试图对其进行任何优化。每次访问(读写)volatile所修饰的变量时,都必须从该变量的内存区域中重新读取,而不要使用寄存器(CPU)中保存的值。这样可保证数据的一致性,防止由于变量优化而出错。
   以下几种情况通常需要volatile关键字:
外围并行设备的硬件寄存器(如状态寄存器);
中断服务程序(ISR)中所访问的非自动变量(Non-automatic Variable),即全局变量;
多线程并发环境中被多个线程所共享的全局变量


二、堆区
1、内存没初始化
通过malloc库函数分配的动态内存,其初值未定义。若访问未初始化或未赋初值的内存,则会获得垃圾值。当基于这些垃圾值控制程序逻辑时,会产生不可预测的行为。
    【对策】在malloc之后调用 memset 将内存初值清零

2、内存分配失败
动态内存成功分配的前提是系统具有足够大且连续可用的内存。内存分配失败的主要原因有:
     1) 剩余内存空间不足;
     2) 剩余内存空间充足,但内存碎片太多,导致申请大块内存时失败;
     3) 内存越界,导致malloc等分配函数所维护的管理信息被破坏。

3、内存释放失败
内存释放失败的主要原因有:
     1) 释放未指向动态内存的指针;
     2) 指向动态内存的指针在释放前被修改;
     3) 内存越界,导致malloc等分配函数所维护的管理信息被破坏;
     4) 内存重复释放(Double Free)。

4、内存分配与释放不匹配
编码者一般能保证malloc和free配对使用,但可能调用不同的实现
【对策】动态内存的申请与释放接口调用方式和次数必须配对,防止内存泄漏。分配和释放最好由同一方管理,并提供专门的内存管理接口。若不能坚持谁申请谁释放,则应进行协商或加代码注释说明。

5、内存越界
【对策】当模块提供动态内存管理的封装接口时,可采用“红区”技术检测内存越界。例如,接口内每次申请比调用者所需更大的内存,将其首尾若干字节设置为特殊值,仅将中间部分的内存返回给调用者使用。这样,通过检查特殊字节是否被改写,即可获知是否发生内存越界。

6、内存泄漏
内存泄漏指由于疏忽或错误造成程序未能释放已不再使用的内存
内存泄漏的真正危害在于其累积性,这将最终耗尽系统所有的内存。因此,一次性内存泄漏并无大碍,因为它不会累积;而隐式内存泄漏危害巨大,因其相比常发性和偶发性内存泄漏更难检测。
     内存泄漏的主要原因有:
     1) 指向已申请内存的指针被挪作他用并被改写;
     2) 因函数内分支语句提前退出,导致释放内存的操作未被执行;
     3) 数据结构或处理流程复杂,导致某些应该释放内存的地方被遗忘;
     4) 试图通过函数指针参数申请并传递动态内存;
     5) 线程A分配内存,线程B操作并释放内存,但分配速度远大于释放速度。
   
 【对策】设计时应规范各动态内存的用途及申请释放的流程,避免指针多用和忘记释放。
     函数内部若存在退出分支,则每个返回之前都应确保释放已成功分配的内存。
     对于挂接内存,应按照分配顺序反向遍历释放各子内存,最后释放父内存(最好能为其提供专门的分配和释放接口)。也可借助柔性数组特性来简化释放操作,尤其是当挂接内存提供给外部调用者使用时:

7、使用已释放堆内存
动态内存被释放后,其中的数据可能被应用程序或堆分配管理器修改。不要再试图访问这块已被释放的内存,否则可能导致不可预料的后果。
    【对策】务必保证已分配的内存块被且仅被释放一次,禁止访问指向已释放内存的指针。若该指针还存在多个副本,则必须保证当它所指向的动态内存被释放后,不再使用所有其他副本。
     避免上述错误发生的常用方法是释放内存后立即将对应的指针设置为空(NULL)。

三、栈区
1、内存未初始化
  未初始化的栈区变量其内容为随机值。直接使用这些变量会导致不可预料的后果,且难以排查。
     指针未初始化(野指针)或未有效初始化(如空指针)时非常危险,尤以野指针为甚。
    【对策】在定义变量时就对其进行初始化。某些编译器会对未初始化发出警告信息,便于定位和修改。

2、堆栈溢出
每个线程堆栈空间有限,稍不注意就会引起堆栈溢出错误。注意,此处“堆栈”实指栈区。
  堆栈溢出主要有两大原因:1) 过大的自动变量;2) 递归或嵌套调用层数过深。

3、内存越界
因其作用域和生存期限制,发生在栈区的内存越界相比数据区更易发现和排查

4、返回栈内存地址
(被调)函数内的局部变量在函数返回时被释放,不应被外部引用
【对策】不要用return语句返回指向栈内变量的指针,可改为返回指向静态变量或动态内存的指针。但两者都存在重入性问题,而且后者还存在内存泄露的危险

 参考链接:

https://www.cnblogs.com/clover-toeic/p/3816644.html

 

标签:释放,动态内存,常见,越界,内存,语音,分配,指针
From: https://www.cnblogs.com/sunshine1218/p/18453774

相关文章

  • 常见的公共 DNS 服务器地址有:谷歌 DNS:8.8.8.8 和 8.8.4.4阿里云 DNS:223.5.5.5 和 223.
    常见的公共DNS服务器地址有:谷歌DNS:8.8.8.8和8.8.4.4阿里云DNS:223.5.5.5和223.6.6.6腾讯DNS:119.29.29.29和182.254.116.116阿里公共DNS:IPv4:223.5.5.5、223.6.6.6IPv6:2400:3200::1、2400:3200:baba::1腾讯公共DNS(DNSPod):IPv4:119.29.29.29IPv6:2402:4e00::百......
  • Linux 网络管理-常见网络管理命令与工具
    Linux常用命令-网络管理常见网络管理命令与工具ip命令安装:aptinstalliproute2或dnfinstalliproute2ifconfig安装:aptinstallnet-tools或dnfinstallnet-toolsifconfig包含了常用的网络管理功能,包括网络接口的启停、网络参数的配置等,但是ifconfig的配置是临......
  • 库卡机器人KR3R540电源模块常见故障维修解决方法
    库卡机器人KR3R540电源模块的常见故障及维修解决方法包括:电源模块无法正常启动:应检查电源模块的电源连接是否正常,以及电源开关是否开启。如果电源连接正常,但驱动器仍然无法启动,可以尝试使用万用表检查驱动器的电源电压是否在正常范围内。如果电源电压过低或过高,都可能导致驱动器......
  • 软件测试面试中常见必问(一)内附答案
    一般面试都会按照简历当中我们写的技能或者项目进行提问,所以我们在简历当中一定要写自己能说上来的东西和对简历中的项目一定要有准备。另外,如果真的不知道就请坦诚相待,直说“不好意思,这里我不太清楚”就可以了,有的面试官也会当场告诉你答案。1.自我介绍虽然简历中都有信息,但是......
  • Kafka的常见问题及解决方案:轻松驾驭流处理的利器
    ApacheKafka,作为一个分布式的流处理平台,因其高吞吐量和横向扩展能力而受到广泛欢迎。然而,在日常使用中,Kafka用户常常面临一些挑战。本文将深入探讨Kafka中的常见问题以及高效解决方案,帮助您更好地驾驭这一强大工具。1. 高延迟问题问题描述:在流数据处理时,用户常常发现数......
  • 在K8S中,Pod的LivenessProbe 探针的常见方式有哪些?
    在Kubernetes中,Pod的LivenessProbe探针用于确定何时重启容器。以下是LivenessProbe的常见方式:ExecAction:在容器内执行命令。如果命令执行成功(返回码为0),则认为容器健康。否则,kubelet会杀死并重启容器。配置示例:livenessProbe:exec:command:-cat......
  • OpenAI 旧金山开发者大会发布五大创新功能 实时语音、视觉微调、模型蒸馏
    在10月1日的 OpenAI旧金山开发者大会(DevDay) 上。OpenAI 公布了五项重大创新,其中“实时API”(RealtimeAPI)的新功能,使得开发者能够创建具有低延迟、AI生成的语音响应功能的应用程序。尽管这一功能不完全等同于ChatGPT的高级语音模式,但其能力已经非常接近,旨在帮助开发者......
  • Python 享元模式:高效利用内存的设计模式
    在Python编程中,随着程序规模的增大和数据量的增加,内存管理变得至关重要。享元模式(FlyweightPattern)作为一种结构型设计模式,为我们提供了一种在某些场景下有效管理内存、提高系统性能的方法。本文将深入探讨Python中的享元模式,包括其概念、关键要点、实现方式、应用场景......
  • OAS常见错误
    OAS使用时的ADB连接错误。原始错误信息ERROR|19:43:07.855|FileNotFoundError:[WinError2]系统找不到指定的文件。┌─────────────────Traceback(mostrecentcalllast)─────────────────┐│C:\Use......
  • 【Kubernetes】常见面试题汇总(五十七)
    目录125.K8S创建服务status为ErrlmagePull?126.不能进入指定容器内部?特别说明:题目  1-68  属于【Kubernetes】的常规概念题,即“汇总(一)~(二十二)”。题目 69-113 属于【Kubernetes】的生产应用题,其中104-113为“情景类”。题目114-132属于【Kube......