0xC0000005: 读取位置 xxx时发生访问冲突

发现一篇写的比较好的文章,记录一下~

Bjarne Stroustrup老爷子说过: 
“C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off.”

最近的工程时不时的出现0xC0000005: 读取位置 xxx时发生访问冲突,导致崩溃。

先看看下面的程序:

#include<iostream>
#include <string>

int main()
{
    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);   //正确

    std::cout << p1 << std::endl;
    std::cout << p2 << std::endl;

    std::cout << p3 << std::endl;
    std::cout << p2 << std::endl;

    //释放内存
    free(p1);
    p1 = NULL;
    return 0;
}

上面的程序在运行的时候就会报错,调试分析:

因为指针变量p1(0x00d7576c)所指向的字符串常量“abcd”后面,也即字符’d’的地址是 0x00d7576c+3=0x00d7576f 。而它后面以地址 0x00d75770 开始的内存块是不属于指针变量p1的,没有访问权限,所以把拷贝自指针变量p2(0x00d75774)指向的字符串“efgh”到以 0x00d75770 为起始地址的内存块中会报错。

如果这样修改:

    char p3[20] = "igkl";
    char * p1 = (char *)malloc(sizeof(char) * 20);
    p1 = p3;
    char * p2 = "efgh";

    strcat(p1, p2);   //正确
    strcat(p3, p2);   //正确

可以把语句 p1 = “abcd”; 改成 p1 = p3;,然后直接使用 strcat( p1, p2 );,这样是合法的。

博客C++“读取位置 0x****** 时发生访问冲突”的可能原因
有指出了一种情况:

malloc一个100内存的空间用于读入文件,当文件的大小超过100时,并且程序中再使用100之后的内存时,就会产生“0xC0000005: 读取位置 xxx时发生访问冲突”这样的错误。

还有可能产生的原因: 
申请的内存没有释放
new后必须delete 
malloc后必须free 
创建内核对象(比如CreateFile,CreateMutex,CreateThread),后必须释放内核对象句柄. 
创建内存映射文件,CreateFileMapping,MapViewOfFile后必须CloseHandle(),UnMapviewofFile 
创建GDI对象后,比如LoadIcon,LoadImage,CreateImageList等等,必须Destroy掉 
创建DC后,比如GetDC(), 必须释放DC句柄 
保留虚拟地址空间 VirtualAlloc(),然后提交物理存储器后,必须释放掉

出现死循环导致内存泄露

所有的第三方类库存在内存泄露相关的BUG

常见的溢出主要有: 
内存分配未成功,却使用了它。
常用解决办法是,在使用内存之前检查指针是否为NULL。如果指针p 是函数的参数,那么在函数的入口处用assert(p!=NULL)进行检查。如果是用malloc 或new 来申请内存,应该用if(p==NULL)或if(p!=NULL)进行防错处理。

内存分配虽然成功,但是尚未初始化就引用它。
内存分配成功并且已经初始化,但操作越过了内存的边界。 
例如在使用数组时经常发生下标“多1”或者“少1”的操作。特别是在for 循环语句中,循环次数很容易搞错,导致数组操作越界。

使用free 或delete 释放了内存后,没有将指针设置为NULL。导致产生“野指针”。

程序中的对象调用关系过于复杂,实在难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面。

不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。

引用\[1\]中提到了一个在Release模式下的异常报错,错误代码为0xC0000005读取位置为0x0000000000000008。这个错误通常是由于访问了无效的内存地址导致的。引用\[2\]中给出了一个示例程序,其中使用了指针p1和p2进行字符串拼接操作,但是由于p1指向的内存块不足以容纳拼接后的字符串,导致访问冲突。引用\[3\]进一步解释了这个问题,指出p1指向的字符串常量"abcd"后面的内存块并不属于p1,因此拷贝p2指向的字符串到这个内存块会导致访问冲突。 根据你提供的问题描述,错误代码为0xC0000005读取位置为0xcdcdcdcd。这个错误通常是由于访问了未初始化的指针或已释放的内存导致的。在你的程序中,可能存在类似的问题,导致访问了无效的内存地址。你可以检查一下你的代码,特别是涉及指针操作的部分,确保指针指向的内存块是有效的,并且没有被提前释放。另外,你还可以尝试在Release模式下使用调试工具来定位错误的具体位置,以便更好地解决这个问题。 #### 引用[.reference_title] - *1* [引发的异常: 0xC0000005: 读取位置 0x0000000200000000 发生访问冲突](https://blog.csdn.net/jacke121/article/details/120339752)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [0xC0000005: 读取位置 xxx发生访问冲突](https://blog.csdn.net/cq_Learnmore/article/details/116522177)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值