转自: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读取写入位置冲突”——正确使用指针访问内存相关推荐

  1. C/C++使用strcpy函数报错:“XXX处有未经处理的异常:0xC0000005:写入位置0x00000000时发生访问冲突”

    strcpy是一种C语言的标准库函数,它的作用是把含有'\0'结束符的字符串复制到另一个地址空间,返回值的类型为char *.其原型声明:char *strcpy(char *dest, const ...

  2. 关于“有未经处理的异常: 0xC0000005: 写入位置 0xfeeefeee 时发生访问冲突”的解...

    版权说明:未经许可,不得转载. 著作权归博主所有. 本博客一切解释权归博主所有.   "0xC0000005"报错的原因是:非法访问内存地址.一般包括读.写.执行三种类型的访问. ...

  3. 《Python基础教程》第7章 再谈抽象

    本章不仅介绍了有关Python语言的知识,还介绍了多个你可能一点都不熟悉的概念.下面来 总结一下. 对象:对象由属性和方法组成.属性不过是属于对象的变量,而方法是存储在属性中的 函数.相比于其他函数, ...

  4. JVM学习笔记之-垃圾回收相关概念 System.gc()的理解 内存溢出与内存泄漏 STW 垃圾回收的并行与并发 安全点与安全区域 再谈引用:强引用 软引用 弱引用 虚引用 终结器引用

    System.gc()的理解 在默认情况下,通过System.gc()或者Runtime. getRuntime ( ).gc ()的调用,会显式触发Full GC,同时对老年代和新生代进行回收,尝试 ...

  5. vb6 串口同时读取写入数据怎么避免冲突_分布式场景下的数据复制究竟怎么做...

    主从复制 集群中有一个主节点,写操作都必须经过主节点完成,读操作主从节点都可以处理. 同步复制 数据在副本上落盘才返回. 优点:保证在副本上的数据是最新数据. 缺点:延迟高,响应慢. 异步复制 数据不 ...

  6. 0xC0000005: 读取位置 0x6C6C6568 时发生访问冲突的原因及解决方法

    程序很简单,就想打印字符串数组中的每一个字符串 void test(char** s, int size) { for (int i = 0; i < size; i++) printf(&qu ...

  7. 0xC0000005: 写入位置 0x00000000 时发生访问冲突的解决办法(内存对齐)

    0xC0000005: 写入位置 0x00000000 时发生访问冲突的解决办法(内存对齐) 顺带总结相关的内存问题: 1)写入位置发生冲突(内存对齐造成) 2)delete造成的this->0 ...

  8. 处有未经处理的异常:0xC0000005 : 读取位置 0x00000000 时发生访问冲突。

    转 首先排除一种小概率事件就是系统冲突导致的,比如系统盘目录存在类似的第三方库文件,程序运行将崩溃,并报错0xC0000005 : 读取位置 0x00000000 时发生访问冲突. 上面的意思就是,你 ...

  9. 异常:0xC0000005: 读取位置 0x00617568 时发生访问冲突。

    0xC0000005: 读取位置 0x00617568 时发生访问冲突. 这个令一个像我这种正在学习的小菜鸟非常崩溃的异常. 对于这个异常,有个大佬总结了一下: 0xC0000005可能出现的原因: ...

最新文章

  1. python sort函数返回值_lambda函数与箭头函数在集合内置函数应用中的对照学习
  2. python代码案例详解-Python综合应用名片管理系统案例详解
  3. php 自增,php 根据自增id创建唯一编号类
  4. 如何判断数组是静态还是动态分配的
  5. day31 Pyhton 面向对象的基础 三大特性
  6. java pid 获取句柄_获取进程pid、根据进程pid获取线程pid、获取线程进程句柄
  7. TypeScript 里的 unknown 和 never
  8. Intelij 添加php注释
  9. bash: mail: command not found的解决方法
  10. python3 socket sendall_全网最详细python中socket套接字send与sendall的区别
  11. myeclipse中删除tomcat 的server后,重新添加进来的方法
  12. Windows下 OpenCV 的下载安装教程(详细)
  13. 计算机考试表格函数应用题,2017年职称计算机考试Excel练习题2
  14. python股票策略_用Python编程彼得林奇PEG价值选股策略
  15. ExpandableListView讲解
  16. 做IT工作应有的10个好习惯
  17. ENSP使用Web界面管理配置流程(防火墙、AC)
  18. 计算机地图制图的过程,第四章计算机地图制图过程.ppt
  19. 箱线图、小提琴图、异常值
  20. 【好用工具推荐系列】跨平台剪贴板工具——快贴

热门文章

  1. 《我的价值观》 潘石屹
  2. 自然语言处理-应用场景-文本生成:Seq2Seq --> 看图说话【将一张图片转为一段文本】
  3. 郭静——在树上唱歌的女孩
  4. fixup或parse_tags物理内存解析 - linux内存管理(四)
  5. c语言第几天的答案,C语言根据日期取其位于一年中的第几天
  6. mysql order by convert函数 优化
  7. 计算机等级考试一般在什么时候?
  8. Python网页爬虫练习:requests库Beautiful爬取bilibili网页信息
  9. Redhat6.5出现不识别CPU
  10. DB2数据库学习篇之最全面的sql语法知识总结