如何正确使用内存

内存|内存的概念、内存的作用、内存的物理结构及内存使用 内存是硬件,是用于存放数据的硬件。程序执行前需要先放到内存中才能被CPU处理。内存是与CPU沟通的桥梁,计算机中所有程序的运行都要依靠内存,内存对计算机的影响非常大。本文简单介绍了内存的概念、作用、物理结构以及使用,内存远不止如此,后续文章会逐步深入讲解。 阅读详情
首先我们要了解内存的分配方式。一般来说,内存的分配方式有三种:
1.从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
2.在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
3.从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。

以上三种分配方式,我们要注意内存生命期的问题:
1.静态分配的区域的生命期是整个软件运行期,就是说从软件运行开始到软件终止退出。只有软件终止运行后,这块内存才会被系统回收
  
2.在栈中分配的空间的生命期与这个变量所在的函数和类相关。如果是函数中定义的局部变量,那么它的生命期就是函数被调用时,如果函数运行结束,那么这块内存就会被回收。如果是类中的成员变量,则它的生命期与类实例的生命期相同
  
3.在堆上分配的内存,生命期是从调用new或者malloc开始,到调用delete或者free结束。如果不掉用delete或者free。则这块空间必须到软件运行结束后才能被系统回收。

下面我们再看看,在使用内存的过程中,我们经常发生一些什么样的错误。以及我们应该采取哪些对策:
发生内存错误是件非常麻烦的事情。编译器不能自动发现这些错误,通常是在程序运行时才能捕捉到。而这些错误大多没有明显的症状,时隐时现,增加了改错的难度。有时用户怒气冲冲地把你找来,程序却没有发生任何问题,你一走,错误又发作了。
  
  常见的内存错误及其对策如下:
  
  1 内存分配未成功,却使用了它。
  
  编程新手常犯这种错误,因为他们没有意识到内存分配会不成功。常用解决办法是,在使用内存之前检查指针是否为NULL。如果指针p是函数的参数,那么 在函数的入口处用assert(p!=NULL)进行检查。如果是用malloc或new来申请内存,应该用if(p==NULL) 或if(p!=NULL)进行防错处理。
2 内存分配虽然成功,但是尚未初始化就引用它。
  
  犯这种错误主要有两个起因:一是没有初始化的观念;二是误以为内存的缺省初值全为零,导致引用初值错误(例如数组)。
  
  内存的缺省初值究竟是什么并没有统一的标准,尽管有些时候为零值,我们宁可信其无不可信其有。所以无论用何种方式创建数组,都别忘了赋初值,即便是赋零值也不可省略,不要嫌麻烦。
  
  3 内存分配成功并且已经初始化,但操作越过了内存的边界。
  
  例如在使用数组时经常发生下标“多1”或者“少1”的操作。特别是在for循环语句中,循环次数很容易搞错,导致数组操作越界。
  
  4 忘记了释放内存,造成内存泄露。
  
  含有这种错误的函数每被调用一次就丢失一块内存。刚开始时系统的内存充足,你看不到错误。终有一次程序突然死掉,系统出现提示:内存耗尽。
  
  动态内存的申请与释放必须配对,程序中malloc与free的使用次数一定要相同,否则肯定有错误(new/delete同理)。
  
  5 释放了内存却继续使用它。
  
  有三种情况:
  
  (1)程序中的对象调用关系过于复杂,实在难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面。
  
  (2)函数的return语句写错了,注意不要返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结束时被自动销毁。
        (3)使用free或delete释放了内存后,没有将指针设置为NULL。导致产生“野指针”。

综上所述,我们应该注意:
  
  1.用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存。
  
  2.不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。
  
  3.避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作。
  
  4.动态内存的申请与释放必须配对,防止内存泄漏。
  
  5.用free或delete释放了内存之后,立即将指针设置为NULL,防止产生“野指针”。
  
  下面举几个经典的错误例子,大家不要犯同样的错误:
  
  1. 返回栈内存指针
  
  char *GetString(void)
  
  {
  
  char *p = "hello world";
  
  return p;
  
  }
  
  char* pGet = GetString();
  
  这段程序编译时没有错误,运行也没有错误,但是你却无法使得返回的pGet指针指向的数据是你想要的“hello world”,因为指针p的生命期是函数GetString内,运行完函数GetString后,p分配的栈空间马上被系统回收了。虽然pGet指向了p 当初分配的内存地址,但是那块地址已经没有内容了。
  
  2.这是一个出现频率非常高的错误
  
  char* pChar = new char;
  
  ……
  
  int a ;
  
  pChar = &a;
  
  ……
  
  delete pChar;
  
  当然这是一个例子,具体的程序各有不同。
  
  这段程序有两个问题。一是pChar = &a;将导致pChar原先分配的空间无法再被获取,就象我们的丢失了朋友的电话号码一样,无法再联系这个朋友了。这就造成了内存泄漏。如果内存 泄漏多了,可能导致系统的崩溃,因为可用的资源将越来越少,直到枯竭为止。第二个问题是delete pChar将导致异常发生,因为这时的pChar已经不是指向动态分配的内存了,而是指向了a分配的栈空间,而栈空间是不能使用delete来回收的,因 此将导致内存异常。
  

cJSON-正确使用防止内存泄漏 主要涉及两个释放内存的函数:cJSON_free和cJSON_Delete,该项目在github上有如下说明: Printing JSON Given a tree ofcJSONitems, you can print them as a string usingcJSON_Print. char *string = cJSON_Print(json); It will allocate a string and print a JSON representation of the tr... 阅读详情

相关推荐

浅谈MOS管的发热原因和解决办法

解读一下开关管发热原因,解决方案和开关损耗测试。

qq_45508321的博客 1万+

Linux系统命令 - 查看内存使用情况

一、 查看内存使用情况 在Linux系统中,大部分操作都通过命令行来完成,因为大部分情况下不开启图形界面。 在服务器环境,则只能通过shell执行操作。 下面介绍查看内存使用情况的相关命令。 包括物理内存(RAM)和交换内存(swap)。 我们经常需要检查服务器的内存使用情况,以及每个进程占用的内存,避免发生资源短缺进而影响用户体验。 对于网站和Web服务,必须具有足够的内存才能处理客户端请求。 ...

铁锚的优快云博客 26万+

5分钟搞定mmdetection3d多模态推理可视化:从KITTI数据集到3D检测结果展示

本文提供了一份快速上手MMDetection3D进行多模态推理可视化的实战指南。文章详细介绍了从环境搭建、KITTI数据集准备,到模型选择、配置解析,再到执行多模态推理并生成3D检测结果可视化的完整流程,旨在帮助开发者在30分钟内快速验证模型并直观展示检测效果。

weixin_29051149的博客 249

计算机内存使用方式

早期计算机内存使用方式 早期的计算机内存使用根本就没有所谓的抽象(考虑如何使用),比如下面这条汇编指令: MOVE REGISTER1,1000 这条汇编代码的作用为,将地址为1000的物理内存上的内容移到REHISTER1中,那是的物理内存给人的映像就为0到一个上限的集合,每个地址上能存一定数目的二进制数,一般都为八位。 以冯诺依曼的计算机设计思路为,CUP现在内存中取指(这里的指,代表指令类型,比如接下来是要做加法还是减法,左移还是右移,构架不同的CUP所用的指令集是不同的,所以就有了X86,X64

Advsance的博客 741

Weblogic安装与部署

27.免密登录,在目录Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain\servers\AdminServer和Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain\servers\Server-TA目录下,新建security\boot.properties文件,13.点击新建按钮,填写服务器名称,服务器监听地址,再点击下一步,最后点击完成。

m0_46259466的博客 6635

LoFTR训练避坑指南:从零到一复现论文训练流程

本文是一份详细的LoFTR模型训练避坑指南,旨在帮助开发者从零开始复现论文训练流程。文章系统性地讲解了环境配置、数据准备、代码调试与显存优化等关键步骤,并针对常见的训练错误提供了解决方案,确保训练过程顺利进行。

weixin_29091837的博客 204

正确使用内存

对于初学者来说,内存是个神秘的空间,程序的绝大部分错误也是由于内存使用不当造成的,而且这些错误往往都是隐藏很深的。因此,如何掌握内存的使用,通晓系统对内存的管理手段,将是软件成功的一个关键因素。 首先我们先了解内存的分配方式。一般来说,内存的分配有三种方式: 1、从静态存储区域分配:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。 2、从

w_16822的博客 470

缺陷检测-金属表面缺陷检测

1介绍 缺陷检测是工业视觉技术中最重要的组成部分。业务广泛,场景丰富,技术难点高、工作量大。针对不同的场景,选择不同的相机和

huneng1991的专栏 5248

如何占用计算机内存,怎么减少电脑内存被占用

我们一直在讨论如何加快电脑的运行速度,一直用清理系统垃圾,清理磁盘空间等各种各样的方法减轻电脑的负担,但是实际上,影响电脑运行速度的因素,其实就集中在CPU、硬盘以及内存三个条件上。今天学习啦小编要讲述的,便是减少电脑内存被占用的方法。减少电脑内存被占用的方法:第一步:查看系统和软件所占用的内存情况1.打开系统的任务管理器,点击上方的“性能”选项,查看当前内存使用情况。2.从这里可以看出内存可能空...

weixin_39568926的博客 1063

超分辨率重建:ESPCN与SRGAN技术对比

超分辨率重建:ESPCN与SRGAN技术对比​ 人工智能,计算机视觉,大模型,AI,超分辨率重建是一种通过技术手段,将低分辨率图像转换为高分辨率图像的过程。它的目的是恢复低分辨率图像中丢失的细节信息,使图像具有更高的清晰度和视觉质量。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 7万+

政务帮办新范式:基于检索增强与多智能体协同的智能系统实践

本文提出了一种多智能体协同的智能政务系统架构,突破传统方案在状态管理、职责过载和感知闭环方面的局限。系统由中央规划智能体、对话引导智能体、参数提取智能体和执行状态分析智能体组成,通过职责分离与显式状态管理实现高效协同。核心创新在于中央决策引擎的确定性逻辑,采用基于规则的状态机设计,确保系统可靠可控。该架构支持自然语言交互、参数自动提取、业务系统操作和视觉闭环验证,能够真正实现"帮办"功能,显著提升政务服务的智能化水平。

469

正确使用动态内存

尽管在开发过程中坚守原则和谨慎编程甚至严格测试,然而内存泄露的错误还是难以杜绝,如何让系统自动查出内存泄露的错误呢?一种比较好的方法是建立日志块,即每次分配内存时记录该内存块的指针和大小,释放时再去除该日志块,如果有内存泄露就会有对应的日志块记录这些内存没有释放,这样就可以提醒程序员进行查错。

jiangjunjie_2005的专栏 2381

【深度解析】解决 NVIDIA 显卡“掉卡”与 Xid 79 错误:开启持久化模式 (Persistence Mode)

【深度解析】解决 NVIDIA 显卡“掉卡”与 Xid 79 错误:开启持久化模式 (Persistence Mode)

Edward的博客 858

Volatile内存语义以及如何正确使用

上述的内存屏障策略是相对保守的,在实际执行的时候,只要不改变volatile的内存语义是可以生省略不必要的屏障的。为了实现volatile语义,编译器在生成字节码的时候,会在指令序列中插入内存屏障来禁止特定类型的处理器排序。读语义:当读一个volatile变量的时候。JMM会把该线程对应的本地内存置为无效,从而从主内存中读取。会把该线程对应的本地内存的共享变量直接刷新到主内存中。写语义:当写一个volatile变量时候,1. volatile变量的写操作。2. volatile变量的读操作。

huangwei2014的博客 390

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

如何正确查看Linux机器内存使用情况

背景 只要工作上涉及到Linux机器,基本上都会有这样一个需求,查看内存使用情况,但是怎么看才正确呢?之前使用的是top命令,一直存在一个误区。 为什么top命令看内存会有误区? top是个很好用的系统分析工具,可以实时查看进程,cpu使用率,内存使用率等情况,有点像windows下的任务管理器。我以前一直以为top看到的就是真正的内存使用情况,后来baidugoogle好久,才

caomiao2006的专栏 9248

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

malloc动态内存如何正确使用

前言常见错误 在实际项目中,经常会需要用到malloc申请动态内存,但使用不当经常会出现内存泄漏问题,下面给出了几种常见的使用错误,以及较为正确的使用方法。 常见错误 使用局部指针变量申请动态内存 #include <stdio.h> #include <string.h> #include <stdlib.h> void malloc_test(char* m, int num) { m = (char *)malloc(sizeof(char) * num);

嵌入式Linux开发从业者,立志做一名优秀的博客输出者! 626

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Fragment的正确使用避免内存泄漏

这里之所以起这个名字,是因为Fragment的用法实在太多,这里为了记录下,给出一个通用,常用的方案,避免造成内存泄漏,只要保证了内存不泄漏,你可以随便折腾Fragment的用法。 用法多体现在: 第一,你可以直接跟activity静态绑定;也可以动态; 第二,使用FragmentManager、FragmentTransaction管理的时候,根据Fragment的显示场景,可以replace(layoutId, newFragment, false); 也可以add,popStack,show, hid

jzlhll123的专栏 1万+
上一篇: memset,memcpy,strcpy 的区别
下一篇: Function Pointers -----PART 1
ybugchen
博客等级 码龄22年 1粉丝 44原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值