首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 100'求文件映射后指针的问题!!!0xC0000005: Access Violation [已结帖,结帖人:devoc]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • devoc
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 结帖率:
    发表于:2008-08-23 00:06:46 楼主
    用文件映射的方式读入一个比较大的文件,如a
    得到内存中文件的指针,转化为char型指针,如pvFile
    现在我需要把文件分为几段处理了后在保存(一个文件的每段大小相同),这里我用了一个随机数,得到每段长度在文件总长度的1/3-1/2之间
    对于没段文件我是这样判断的
    C/C++ code
    while(*pvFileO!=NULL) { //处理每段数据 //... //再对结尾处理 if(*(pvFile+nFileLen)==NULL) //最后一段如果小于分隔段,nFileLen为分割的段长 { //处理结尾的一段 } }


    上面是整个程序的大概思想,但运行会出现"遇到问题。。需要调试。。"的对话框,单步跟踪发现是运行到最后一段的时候,就是长度小于段长,就会出现0xC0000005: Access Violation的警告。我有两个问题:
    1、我不知道这儿是怎么回事,映射后的文件,就算指针指出了他的区域,怎么就访问受限了呢?
    2、如果不能这样处理,那么大家有什么好的方法么?
    100  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • devoc
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-23 00:07:521楼 得分:0
    漏了点,上面处理完每段数据后会对pvFile+=nFileLen;
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cnzdgs
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 6

      2

      15

    发表于:2008-08-23 00:17:242楼 得分:20
    1、最后一段pvFile+nFileLen超出了映射的范围,*(pvFile+nFileLen)就是访问了无效的内存地址,出错是正常的。
    2、用一个变量记录当前处理了多少数据,与映射大小比较来确定最后一段。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • devoc
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-23 00:39:093楼 得分:0
    引用 2 楼 cnzdgs 的回复:
    1、最后一段pvFile+nFileLen超出了映射的范围,*(pvFile+nFileLen)就是访问了无效的内存地址,出错是正常的。
    2、用一个变量记录当前处理了多少数据,与映射大小比较来确定最后一段。

    我开始也觉得是这里的错误,现在我改成这种形式
    C/C++ code
    int nSeg=nSize/nFileLen; //取段长为nFileLen的段数 int nlSeg=(nSize%nFileLen!=0)?(nSize%nFileLen):0; //取结尾一段的长度 for(int t=0; t<nSeg; t++) { //处理完整的段 //... if(t!=nSeg-1) pvFile+=nFileLen; else continue; } if (nlSeg!=0) //最后一段如果小于分隔段 { //处理最后一段 }


    但现在出来一个Debug Assertion Failed!
    报错在_CtrIsValidHeapPointer(pUserData)

    点击终止后还是会弹出内存不能为read  - -lll郁闷
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • shanying_0
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-23 08:31:294楼 得分:20
    你最后一端的处理.可以用文件的总长-已经读取的长度来处理.这样就ok了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • yyunffu
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-23 08:58:455楼 得分:20
    记录文件总长度,指针移动时判断是否到文件尾,避免访问非法内存。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • devoc
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-23 09:29:356楼 得分:0
    引用 4 楼 shanying_0 的回复:
    你最后一端的处理.可以用文件的总长-已经读取的长度来处理.这样就ok了


    引用 5 楼 yyunffu 的回复:
    记录文件总长度,指针移动时判断是否到文件尾,避免访问非法内存。


    我上面int nSeg=nSize/nFileLen;    //取段长为nFileLen的段数
    int nlSeg=(nSize%nFileLen!=0)?(nSize%nFileLen):0; //取结尾一段的长度
    这样处理也可以吧,但是在调试的时候在每次结尾fclose的时候会出现
    _CtrIsValidHeapPointer(pUserData)错误,网上查了是内存泄漏,但我其中只new了一个数组
    char *hydata=new char[nFileLen];
    处理完所有数据后delete[] hydata;就会出错。不知道这是怎么回事
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cnzdgs
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 6

      2

      15

    发表于:2008-08-23 13:50:367楼 得分:20
    按3楼的做法就对了,现在遇到的是另外的问题,这问题看起来不是内存泄露(内存泄露一般不会产生异常),像是内存访问越界,破坏了其它内存中的数据。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • jszj
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-23 14:14:018楼 得分:20
    是一个问题引起的。

    1. if(*(pvFile+nFileLen)==NULL) 这一句有问题
    不管pvFile是否为0,即使你超出了范围,超出了你的文件的范围,pvFile+nFileLen之后还是不会为0,所以这样判断你的循环会一直持续下去而不会结束
    解决办法就是楼上的那些方法,记录文件的长度,然后判断是否达到了文件长度,到了就退出

    2. 我不知道在你的实际代码中, char *hydata=new char[nFileLen]; 是否和pvFile为同一个变量,如果是,那就有问题了,如果不是,不知道你是如何做的,但如果是按照下面的方法,应该是没有错的:
    char *hydata=new char[nFileLen];
    char *pvFile = hydata;
    然后拿pvFile做你的循环处理,结束之后
    delete[] hydata;
    hydata = NULL;
    而不是
    delete[] pvFile;
    pvFile = NULL;
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • devoc
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-24 12:53:139楼 得分:0
    引用 8 楼 jszj 的回复:
    是一个问题引起的。

    1. if(*(pvFile+nFileLen)==NULL) 这一句有问题
    不管pvFile是否为0,即使你超出了范围,超出了你的文件的范围,pvFile+nFileLen之后还是不会为0,所以这样判断你的循环会一直持续下去而不会结束
    解决办法就是楼上的那些方法,记录文件的长度,然后判断是否达到了文件长度,到了就退出

    2. 我不知道在你的实际代码中, char *hydata=new char[nFileLen]; 是否和pvFile为同一个变量,如果是,那就有…


    谢谢jszj ,cnzdgs
    做出来了,说下我的流程吧,也给做这方面的朋友一个帮助。
    pvFileO是文件映射后的文件首址指针,hyFile是带写入的文件,需wb+打开。
    nFileLen是一个小于这个文件一半大小的随机数

    C/C++ code
    {//大循环,对每个文件处理 int nSeg=nSize/nFileLen; //取段长为nFileLen的段数 int nlSeg=(nSize%nFileLen!=0)?(nSize%nFileLen):0; //取结尾一段的长度 char *hydata=new char[nFileLen]; for(int t=0; t<nSeg; t++) { //处理完整的段... memcpy(hydata,pvFileO,nFileLen); fwrite(pvFileO,nFileLen,1,hyFile); pvFile+=nFileLen; //完整的段都要加段长 } if (nlSeg!=0) //最后一段如果小于分隔段 { //处理最后一段... memcpy(hydata,pvFileO,nlSeg); fwrite(hydata,nlSeg,1,hyFile); } delete[] hydata; }

    如果这样处理,文件数大过5个时会出错,就是上面说的那种错误,不知道为什么,因为我后面也delete了申请的hydata啊。
    C/C++ code
    {//大循环,对每个文件处理 int nSeg=nSize/nFileLen; //取段长为nFileLen的段数 int nlSeg=(nSize%nFileLen!=0)?(nSize%nFileLen):0; //取结尾一段的长度 char *hydata=new char[nFileLen]; for(int t=0; t<nSeg; t++) { //处理完整的段... fwrite(pvFileO,nFileLen,1,hyFile); pvFile+=nFileLen; //完整的段都要加段长 } if (nlSeg!=0) //最后一段如果小于分隔段 { //处理最后一段... fwrite(pvFileO,nlSeg,1,hyFile); } }

    这样就没问题了。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cnzdgs
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 6

      2

      15

    发表于:2008-08-24 13:14:2710楼 得分:0
    这么做是逃避问题,并不是解决问题,不delete会造成内存泄露,留下了问题隐患,另外现有问题不查清楚,可能还有引起其它错误。你查一下省略的代码中有没有内存访问越界或者其它形式修改了hydata指针。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • devoc
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-25 03:17:2911楼 得分:0
    引用 10 楼 cnzdgs 的回复:
    这么做是逃避问题,并不是解决问题,不delete会造成内存泄露,留下了问题隐患,另外现有问题不查清楚,可能还有引起其它错误。你查一下省略的代码中有没有内存访问越界或者其它形式修改了hydata指针。

    呵呵,上边直接写文件的fwrite(pvFileO,nFileLen,1,hyFile); 没有用到char *hydata=new char[nFileLen];
    写多了点点,呵呵,不过上面用数组那块我真找不出来怎么出错的,莫名其妙的因为。^ ^
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • devoc
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-09-01 01:39:3212楼 得分:0
    问题解决了,原来是我申请的动态数组,应该多申请以为,填上0,就解决了,谢谢大家
    结贴给分!
    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright © 2000-2008, CSDN.NET, All Rights Reserved