再谈“0xC0000005读取写入位置冲突”——正确使用指针访问内存
转自:http://www.typecodes.com/cseries/pointermemaccess0xC0000005.html
在前面一篇文章中,总结了错误使用指针指向一个字符串常量,然后对该字符串常量进行写入操作导致出错:“未经处理的异常:0xC0000005: 读取/写入位置发生访问冲突”。这篇文章继续使用指针来探索这个问题。
1 测试程序:“异常: 0xC0000005: 写入位置 0xxxxxxxxx 时发生访问冲突”
下面是一个测试程序,主要是字符串的“连接”——strcat函数,malloc有迷惑性。其中,指针p1指向malloc在堆上开辟的连续内存块,数组p3是一种正确的字符连接方法。
/*** @FileName : pointermemaccess0xC0000005.c* @Author : vfhky http://www.typecodes.com 2014.08.25 20:00* @Functions: 不正确使用指针p1导致出现“异常: 0xC0000005”和正确使用数组实现字符串的连接
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main( int argc, char * argv[] )
{char * p1 = (char *)malloc( sizeof(char)*20 );char p3[20]= "igkl";char * p2 = "efgh";p1 = "abcd"; //p1指向字符串"abcd"的首地址, 而不是把"abcd"拷贝到malloc开辟的内存块中strcat( p1, p2 ); //报错: 0xC0000005异常,访问冲突strcat( p3, p2 ); //正确printf( "p1=[%s], p2=[%s]\n", p1, p2 );printf( "p3=[%s], p2=[%s]\n", p3, p2 );//释放内存free( p1 );p1 = NULL;return 0;
}
</pre><pre name="code" class="cpp">
<h3><span style="font-family: Arial, Helvetica, sans-serif;">2 在vs中设置断点并调试</span></h3>如下图设置好断点后,单步执行到第10行。此时指针变量p1的值是 0x008734c0 ,p2的值是 0x00d75774 ,数组p3的起始地址是 0x0036f928 。
<img src="https://img-blog.csdn.net/20141205215314511?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRmx5aW5nQmlyZF9TWEY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
<span style="font-family: Arial, Helvetica, sans-serif;">
</span>
2.1详细查看指针变量p1、p2以及数组p3的内存情况:(第10行)
此时,指针变量p1通过语句 char * p1 = (char *)malloc( sizeof(char)*20 ); 指向起始地址为 0x008734c0 到 地址 0x008734d3 的内存块(大小为 20 字节)。
<img src="https://img-blog.csdn.net/20141205215447003?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRmx5aW5nQmlyZF9TWEY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
指针变量 p2 通过执行 char * p2 = "efgh"; 指向起始地址为 0x00d75774 的字符串“efgh”(共占 4 字节)。
<img src="https://img-blog.csdn.net/20141205215550296?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRmx5aW5nQmlyZF9TWEY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
<span style="font-family: Arial, Helvetica, sans-serif;">
</span>
<span style="font-family: Arial, Helvetica, sans-serif;">数组 p3 通过 char p3[20]= "igkl"; 开辟了起始地址为 0x0036f928 的内存块(共占 4 字节),存储字符串“igkl”。</span>
<img src="https://img-blog.csdn.net/20141205215631773?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRmx5aW5nQmlyZF9TWEY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
2.2继续单步调试并查看内存情况:(第11行)
上述变量初始化完毕后,单步执行到第 11 行的断点。这时指针变量p1由最初的指向 0x008734c0 变成指向字符串“abcd”的地址 0x00d7576c 。p2 的地址仍不变(0x00d75774),p3的地址也不变(0x0036f928)。
<img src="https://img-blog.csdn.net/20141205215813797?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRmx5aW5nQmlyZF9TWEY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
详细查看指针变量p1的内存情况:起始地址是 0x00d7576c ,该内存块存储的字符串是“abcd”。
2.3继续单步调试并查看内存情况:(第12行)
然后,单步执行到第 12 行的断点,出现错误:test.exe 中的 0x0f85d2e9 (msvcr100d.dll) 处有未经处理的异常: 0xC0000005: 写入位置 0x00d75770 时发生访问冲突。也即在执行第11行的 strcat( p1, p2 ); 语句时,发生内存访问错误。该语句是把作为src的指针变量p2(0x00d75774)指向的内存块中的字符串“efgh”拷贝一份,然后复制到作为dst的指针变量p1(0x00d7576c)所指向内存块中的的字符串常量“abcd”后面。调用堆栈可以看到,当执行 msvcr100d.dll!strcat(unsigned char * dst, unsigned char * src) 对应的strcat.asm汇编文件中第178行语句 mov [edi], edx 时出错。
3 原因分析
其实,通过上面的单步调试,我们也已经知道原因了。现总结一下:因为指针变量p1(0x00d7576c)所指向的字符串常量“abcd”后面,也即字符'd'的地址是 0x00d7576c+3=0x00d7576f 。而它后面以地址 0x00d75770 开始的内存块是不属于指针变量p1的,没有访问权限,所以把拷贝自指针变量p2(0x00d75774)指向的字符串“efgh”到以 0x00d75770 为起始地址的内存块中会报错。可以把语句 p1 = "abcd"; 改成 p1 = p3;,然后直接使用 strcat( p1, p2 );,这样是合法的。
再谈“0xC0000005读取写入位置冲突”——正确使用指针访问内存相关推荐
- C/C++使用strcpy函数报错:“XXX处有未经处理的异常:0xC0000005:写入位置0x00000000时发生访问冲突”
strcpy是一种C语言的标准库函数,它的作用是把含有'\0'结束符的字符串复制到另一个地址空间,返回值的类型为char *.其原型声明:char *strcpy(char *dest, const ...
- 关于“有未经处理的异常: 0xC0000005: 写入位置 0xfeeefeee 时发生访问冲突”的解...
版权说明:未经许可,不得转载. 著作权归博主所有. 本博客一切解释权归博主所有. "0xC0000005"报错的原因是:非法访问内存地址.一般包括读.写.执行三种类型的访问. ...
- 《Python基础教程》第7章 再谈抽象
本章不仅介绍了有关Python语言的知识,还介绍了多个你可能一点都不熟悉的概念.下面来 总结一下. 对象:对象由属性和方法组成.属性不过是属于对象的变量,而方法是存储在属性中的 函数.相比于其他函数, ...
- JVM学习笔记之-垃圾回收相关概念 System.gc()的理解 内存溢出与内存泄漏 STW 垃圾回收的并行与并发 安全点与安全区域 再谈引用:强引用 软引用 弱引用 虚引用 终结器引用
System.gc()的理解 在默认情况下,通过System.gc()或者Runtime. getRuntime ( ).gc ()的调用,会显式触发Full GC,同时对老年代和新生代进行回收,尝试 ...
- vb6 串口同时读取写入数据怎么避免冲突_分布式场景下的数据复制究竟怎么做...
主从复制 集群中有一个主节点,写操作都必须经过主节点完成,读操作主从节点都可以处理. 同步复制 数据在副本上落盘才返回. 优点:保证在副本上的数据是最新数据. 缺点:延迟高,响应慢. 异步复制 数据不 ...
- 0xC0000005: 读取位置 0x6C6C6568 时发生访问冲突的原因及解决方法
程序很简单,就想打印字符串数组中的每一个字符串 void test(char** s, int size) { for (int i = 0; i < size; i++) printf(&qu ...
- 0xC0000005: 写入位置 0x00000000 时发生访问冲突的解决办法(内存对齐)
0xC0000005: 写入位置 0x00000000 时发生访问冲突的解决办法(内存对齐) 顺带总结相关的内存问题: 1)写入位置发生冲突(内存对齐造成) 2)delete造成的this->0 ...
- 处有未经处理的异常:0xC0000005 : 读取位置 0x00000000 时发生访问冲突。
转 首先排除一种小概率事件就是系统冲突导致的,比如系统盘目录存在类似的第三方库文件,程序运行将崩溃,并报错0xC0000005 : 读取位置 0x00000000 时发生访问冲突. 上面的意思就是,你 ...
- 异常:0xC0000005: 读取位置 0x00617568 时发生访问冲突。
0xC0000005: 读取位置 0x00617568 时发生访问冲突. 这个令一个像我这种正在学习的小菜鸟非常崩溃的异常. 对于这个异常,有个大佬总结了一下: 0xC0000005可能出现的原因: ...
最新文章
- python sort函数返回值_lambda函数与箭头函数在集合内置函数应用中的对照学习
- python代码案例详解-Python综合应用名片管理系统案例详解
- php 自增,php 根据自增id创建唯一编号类
- 如何判断数组是静态还是动态分配的
- day31 Pyhton 面向对象的基础 三大特性
- java pid 获取句柄_获取进程pid、根据进程pid获取线程pid、获取线程进程句柄
- TypeScript 里的 unknown 和 never
- Intelij 添加php注释
- bash: mail: command not found的解决方法
- python3 socket sendall_全网最详细python中socket套接字send与sendall的区别
- myeclipse中删除tomcat 的server后,重新添加进来的方法
- Windows下 OpenCV 的下载安装教程(详细)
- 计算机考试表格函数应用题,2017年职称计算机考试Excel练习题2
- python股票策略_用Python编程彼得林奇PEG价值选股策略
- ExpandableListView讲解
- 做IT工作应有的10个好习惯
- ENSP使用Web界面管理配置流程(防火墙、AC)
- 计算机地图制图的过程,第四章计算机地图制图过程.ppt
- 箱线图、小提琴图、异常值
- 【好用工具推荐系列】跨平台剪贴板工具——快贴