“内存不能为read/written”是什么原理?

“内存不能为read/written”是什么原理:

翻译错误,原文:This memory cannot be read/written,应当翻译为内存不能被读取/写入

内存有个存放数据的地方叫缓冲区。

当程序把数据放在缓冲区,需要操作系统提供的“功能函数”来申请,如果内存分配成功,函数就会将所新开辟的内存区地址返回给应用程序,应用程序就可以通过这个地址使用这块内存。这就是“动态内存分配”,内存地址也就是编程中的“光标”。内存不是永远都招之即来、用之不尽的,有时候内存分配也会失败。

当分配失败时系统函数会返回一个0值,这时返回值“0”已不表示新启用的光标,而是系统向应用程序发出的一个通知,告知出现了错误。作为应用程序,在每一次申请内存后都应该检查返回值是否为0,如果是,则意味着出现了故障,应该采取一些措施挽救,这就增强了程序的“健壮性”。

若应用程序没有检查这个错误,它就会按照“思维惯性”认为这个值是给它分配的可用光标,继续在之后的执行中使用这块内存。真正的“0”地址内存区储存的是计算机系统中最重要的“中断描述符表”,绝对不允许应用程序使用。在没有保护机制的操作系统下(如DOS),写数据到这个地址会导致立即当机,而在健壮的操作系统中,如Windows等,这个操作会马上被系统的保护机制捕获,其结果就是由操作系统强行关闭出错的应用程序,以防止其错误扩大。

这时候,就会出现上述的内存不能为“read”错误,并指出被引用的内存地址为“0x00000000“。内存分配失败故障的原因很多,内存不够、系统函数的版本不匹配等都可能有影响。因此,这种分配失败多见于操作系统使用很长时间后,安装了多种应用程序(包括无意中“安装”的病毒程序),更改了大量的系统参数和系统档案之后。

在使用动态分配的应用程序中,有时会有这样的情况出现:程序试图读写一块“应该可用”的内存,但不知为什么,这个预料中可用的光标已经失效了。有可能是“忘记了”向操作系统要求分配,也可能是程序自己在某个时候已经注销了这块内存而“没有留意”等等。注销了的内存被系统回收,其访问权已经不属于该应用程序,因此读写操作也同样会触发系统的保护机制,企图“违法”的程序唯一的下场就是被操作终止执行,回收全部资源。计算机世界的法律还是要比人类有效和严厉得多啊!像这样的情况都属于程序自身的BUG,你往往可在特定的操作顺序下重现错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
jZoomer开源项目主页:<br>http://code.google.com/p/jzoomer/<br>发布包下载地址:http://code.google.com/p/jzoomer/downloads/list<br>SVN下载地址:<br>http://jzoomer.googlecode.com/svn/trunk/<br><br>软件名:jZoomer<br>版本号:1.2.0<br>作者:talent_marquis<甜菜侯爵><br>联系方式:talent_marquis#163.com, marquisx.tz#google.com<br><br>简介:<br>jZoomer 是一款基于SWT/JFace的桌面应用软件<br>功能:<br>·动态放大镜功能<br>·静态图片缩放功能<br>·颜色拾取功能<br>·测量尺功能<br><br>特性:<br>·支持鼠标拖拽窗体和小控件<br>·支持国际化<br>·可扩展架构<br><br>日志:<br>20080621<br>1. Bug修正:<br> ·修正退出时报异常的Bug<br>2. 功能添加:<br> ·实现测量功能,可测量选中区域大小<br>3. 核心调整:<br> ·在system.properties中添加“tray.message.show”字段用以控制是否在托盘区显示提示信息<br> ·实现TrackerAction用以实现测量功能<br>4. 版本变更:<br> 版本升级为1.2.0<br><br>20080620<br>1. Bug修正:<br> ·修正程序退出时会报异常的Bug<br>2. 功能添加:<br> ·实现左键单击托盘区图标,主窗口开启/隐藏功能<br>3. 核心调整:<br>4. 版本变更:<br> 版本升级为1.1.4<br><br>20080619 2nd<br>1. Bug修正:<br> ·修正开始/暂停监视切换时有时会报空指针异常的错误<br>2. 功能添加:<br> ·实现静止时图片的缩放<br>3. 核心调整:<br> ·动态\静止开关中对图片处理的逻辑改变,以实现静止时图片的缩放功能<br> ·ZoomAction中zoomIn、zoomOut方法更新,支持对静止图片的缩放<br>4. 版本变更:<br> 版本升级为1.1.3<br> <br>20080619<br>1. Bug修正:<br> ·修正取色开启时鼠标双击取色后,色彩信息显示不正常的bug<br>2. 功能添加:<br> ·隐藏/取色后会在系统托盘区有信息提示<br>3. 核心调整:<br> ·在trayItem中加入tooltip用于辅助信息提示<br>4. 版本变更:<br> 版本升级为1.1.2<br><br>20080618 2nd<br>1. Bug修正:<br>2. 功能添加:<br> ·添加用户手册中文版V1.1<br> ·添加用户手册英文版V1.1<br> ·添加ant编译文件,使用“ant package”即可轻松打包发布文件<br> ·调整system.properties的排版,方便阅读<br>3. 核心调整:<br> ·加入fatjar.jar架包,用于打包编译<br>4. 版本变更:<br> 版本升级为1.1.1<br><br>20080618<br>1. Bux修正:<br> ·修正工程中加载lib路径不正确的bug<br> ·修正鼠标滚轮在停止取图监视时使用上的Bug<br> ·修正鼠标进入窗口后,还可以开启监视的Bug<br>2. 功能添加:<br> ·添加色彩信息面板<br> ·实现取色功能,用Ctrl+C开启,双击可以直接取色至剪贴板,单击暂停/开始取色<br>3. 核心调整:<br> ·在Google Code上添加了SVN地址用于维护,地址为:https://jzoomer.googlecode.com/svn/trunk/<br> ·重构鼠标拖拽Widget和面板的方法,增强其扩展性<br> ·添加ColorInfoPanel用于显示和拾取颜色<br> ·在ColorAction添加ColorInfoPanel相关的资源、逻辑和方法<br> ·添加TrackerAction用以实现对图片大小的测量(未实现)<br>4. 版本变更:<br> 版本升级为1.1<br>5. 待做事项:<br> ·停止监控时图片的缩放<br> ·对图片大小的测量(width=xxxpx,height=xxxpx)<br> ·色彩信息面板样式的美化<br> ·build.xml文件<br><br>20080617<br>1. Bug修正:<br> ·修正进出窗口时会报异常的Bug<br>2. 功能添加:<br> ·将开始/暂停监控的快捷键更改为Ctrl+Z<br> ·支持容器内部控件的拖拽(按住Ctrl键)<br> ·支持拖拽容器时移动整个Shell(在空白处)<br> ·拖拽时鼠标变成小手形状<br> ·添加exit.confirm属性用以判断是否在退出时弹出提示框<br>3. 核心调整:<br> ·添加canvas用于对静止截图的处理<br> ·添加Tracker用于测量<br> ·添加Label用于信息提示<br> ·添加ColorAction用于对静止截图的处理<br>4. 版本变更:<br> 版本升级为1.03<br><br>20080616 2nd<br>1. Bug修正:<br> ·修正暂停监控时调整窗口大小,显示图像错乱的Bug<br>2. 功能添加:<br> ·添加设定背景色属性background.color<br>3. 核心调整:<br> ·去掉canvas,直接将采样图片放于container上,便于以后进一步在container上添加组件及操作<br>4. 版本变更:<br> ·版本升级为1.02<br><br>20080616<br>1. Bug修正:<br> ·暂未修正无法通过修改配置文件切换语言的Bug<br>2. 功能添加:<br> ·添加使用手册英文版v1.0<br> ·如需软件显示语言自动随系统语言切换,只需将System.properties中“locale”属性置空即可<br> ·调整缩放范围,使其既可放大屏幕也可缩小屏幕<br>3. 核心调整:<br> ·添加SWT/JFace的jar包到工程lib目录下<br> ·BasicWindow添加对鼠标移动点击的事件监听,以实现组件可用鼠标拖拽功能<br> ·BasicWindow添加在屏幕中央显示/随鼠标位置显示方法<br> ·更改屏幕采样并缩放的核心算法,使其缩放质量可以调整,支持缩小屏幕,且采样速度更快<br>4. 版本变更:<br> ·版本升级为1.0.1<br>5. 待做事项:<br> ·使用手册英文版<br> ·采样图片截取:只截取可见部分<br> ·对基类添加:随鼠标拖动功能,自动在屏幕中央显示功能,自动随鼠标显示功能<br> ·打包后无法通过修改配置文件切换语言(打包之前可以)<br> ·整理需要到的jar包,从eclipse中提取出来放到lib目录下<br> ·设置滚轮放大缩小可以开启/取消<br><br>20080615<br>1. Bug修正:<br> ·解决内存溢出Bug<br> ·解决字符串乱码Bug<br> `解决拖拽位置不正常Bug<br>2. 功能添加:<br> ·添加SystemPropertiesReader类,用于解析系统配置文件system.properties<br> ·完成软件的国际化,可根据需要切换英文/中文(暂时只能在启动前配置)<br> ·添加快捷键和部分图标<br> ·实现关闭到系统托盘效果<br>3. JZoomer v1.0 发布<br><br>20080614<br>1. 重新设计框架,提高其重用性<br>2. 实现功能:<br> ·字符串国际化<br> ·系统文件可编辑<br> ·系统托盘显示<br> ·支持滚轮缩放功能<br> ·控件拖拽功能<br> <br>20071227<br>1. JExplorer实现,初步了解JFace框架的设计思想,了解Action的使用方法<br><br>20070730<br>1. ColorPicker实现,其中含有部分放大镜功能,但有内存溢出Bug
这段代码有一些问题: 1. 使用了绝对地址访问内存,容易造成程序的移植性差,建议使用指针或全局变量来代替。 2. 没有在主函数中初始化 i 和 ADC,可能会导致程序出错。 3. 没有使用延时函数等待 ADC 转换结果完成,可能导致读取到错误的数据。 4. 每次读取 ADC 数据时都需要重新配置 ADC 0808 的控制信号,建议在初始化时只配置一次。 下面是对代码的改进: ``` #include <reg52.h> #define uchar unsigned char #define uint unsigned int uchar ADCDat[8]; uchar *pADCDat = ADCDat + 6; // 使用指针代替绝对地址 sbit EOC = P3^3; void delay(uint t) // 延时函数 { uint i, j; for(i=0; i<t; i++) { for(j=0; j<125; j++); } } void ADC_Init() // 初始化 ADC0808 { XBYTE[0x7fff] = 0x80; // 控制字节1,选择单端模式,参考电压为 +5V XBYTE[0x7ffe] = 0x07; // 控制字节2,选择通道0 } void ADC_Read() // 读取 ADC 数据 { *pADCDat = XBYTE[0x7fff]; // 读取 ADC 数据 pADCDat--; // 指针前移 if(pADCDat < ADCDat) // 判断是否到达数组末尾 { pADCDat = ADCDat + 6; } XBYTE[0x7ffe] = ((pADCDat - ADCDat) & 0x07) | 0x08; // 选择下一个通道,并触发 ADC 转换 } void main() { ADC_Init(); while(1) { if(EOC == 1) { delay(1); // 等待 ADC 转换完成 ADC_Read(); } P1 = ADCDat[6]; } } ``` 改进后的代码使用指针代替绝对地址,增加了延时函数等待 ADC 转换结果完成,只在初始化时配置 ADC 0808 的控制信号,提高了程序的可移植性和可读性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值