为啥会迅雷任务出错解决办法,谁有解决的办法?

点击预约 学习规划
预约学习规划
点击预约 学习规划
预约学习规划
怎样克服会做的题但是总出错?
10:17:21  来源:本站原创
最近很多同学反映,在考试过程中,容易马虎,每次都丢了很多不该丢的分。
具体症状如下:题目看错,难题会做,简单送分题做错,思路正确但计算出错、抄错导致丢分或算不下去
&&&&& 根据大量的抽查,发现粗心马虎丢分的原因大致归为两条,并给出相应的解决方法。
1、习惯于依赖知识点,看到题马上就用知识点去写,忽略了问题问什么,题目条件是什么
题目看错的原因:1、最多的是因为看到题目非常熟悉,想都不想就做,导致错误;2、精神恍惚看错(不认真,这种情况极少,通常考试时注意力是非常集中的)
解释:很多同学看到题目感觉很熟悉很简单,想都不想就开始算,结果一不小心方向就错了,没有弄清楚问题是什么,忽略了题目条件表述和你以前熟悉的题型上细微的差别,导致做错。这是过于想当然造成的,中了命题人的陷阱。这属于&兴奋&型马虎。而真正的&看错&题目,指的是精神不集中不认真导致看错,这个除非考生心不在焉,不把考试放在心上,或者因为生病,基本上不可能出现这种错误的。但是很多 同学认为自己&粗心&看错是因为精神恍惚,其实本质上也是由于过于兴奋或者过于紧张,题目一看,见过,兴奋,然后回忆,不自觉忽略了细节。或者因为没见 过,紧张,开始回忆知识点,也忽略了细节。
【解决方法】做题的时候,一定要先看完再写,不要看的过程就马上产生解题的念头。有时候你猜中了开头,却忽略了结尾。一定要看清楚问什么,题目条件是什么 后,再思考,就可以避免这种错误。做题要以题目本身为出发点。根据问题、题设开读懂题意。题目让干什么就干什么,千万不能想当然。
2、个人习惯过于分散。喜欢心算,心里想着怎么解答,结果写的和心里想的不一样
计算错误多的原因:1、喜欢心算造成的;2、草稿乱打,东一块西一块;3、太随心所欲,所以容易抄错。
解释:这个多半与考生性格有关。一般容易犯这类毛病的考生都有&随手乱丢东西&的毛病。在考试时,喜欢心算。宁愿在脑海里推演步骤,强行记住结果,也不愿 意写出来。如果实在要打草稿,多半信手拈来,草稿纸一片混乱,随便找个空白处就开始计算,形成东一块、西一块的拼凑型草稿,结果一不小心抄错。更有甚者, 由于打草稿过于随意,考试一紧张,找不到之前计算的部分,或者过于随意,笔迹夸张,自己不认识或抄错。这就是计算错误的根本原因。
【解决方法】这个属于习惯问题,平时做任何题,凡是涉及计算的,一定要打草稿,并且要规范。平时日常生活可以养成&东西摆放整齐&、&哪里拿来就放回哪里去&、&第一时间处理要事,不要拖到最后才匆忙应付完成&的生活习惯,也有助于培养考试时的细心、精确,从而避免出错。
相关课程推荐
小学春季精品1对1课程
定制专属于你的学习方案
报名电话:
初中春季精品1对1课程
定制专属于你的学习方案
报名电话:
高中春季精品1对1课程
定制专属于你的学习方案
报名电话:
意见反馈电话:010-  邮箱:
广州六年级Q群: |
广州初中Q群: | 广州高中Q群:库存老是出错,搞得其他的都一糟,这个问题该怎么解决,有没有好的办法?_百度知道
库存老是出错,搞得其他的都一糟,这个问题该怎么解决,有没有好的办法?
我有更好的答案
  下面我们来分享一个仓库管理解决方案:经销商/生产厂家 仓库管理弊端:一、 库存管不准,每次盘点盈亏数较大;二、 商品备货无根据,畅销的商品断货,滞销的商品库存很高,不能合理的控制仓库周转率;三、 仓库和财务以及业务不能很好的衔接工作;四、 客户订单不能及时的配送以及不能很好的进行车辆调度;五、 库存出现盈亏的时候,无据可查;六、 仓库的货龄管理问题,导致仓库的过期货和临期品很多;七、 仓库内的残次品和正常商品混堆;八、 发货出库时,商品发错、漏发、重发;针对国内 经销商/生产厂家 仓库管理进行调查,发现仓库管理不好,主要包括以下几个原因:一、 仓库管理没有规章制度,仓库好比菜园地,所有人员随意进出,甚至很多的员工在仓库内部抽烟;二、 公司的管理层没有仓库管理意识,自己带头在违反公司的仓库管理制度,忽视消防意识;三、 无单发货,就是说仓库没有看到公司开具的出库单就随意出库;四、 仓库内部好坏货,没能分开堆放,导致仓库内部很乱;五、 仓库内部临期商品和正常商品没有合理的分开堆放;六、 公司的退货不及时处理,需要报损的商品没有及时报损;七、 仓库的盘点不勤快,导致仓库的盈亏数发生后,由于盘点时间跨度太长,无法查到什么原因造成的;八、 仓库的货物的安全库存没能合理的控制,导致该有的没有,不需要的积压;九、 仓库没有专业的报表,没有任何的分析数据,全部凭仓管的经验;十、 仓库的入库制度不严格,导致仓库内部的临期商品没必要的增加;十一、 仓库的管理职责不明确,赏罚不分明,导致员工没有主人翁意识;十二、发货的责任心不强,错发、漏发、重发时常出现,并且不能及时发现,甚至无人监督;综上所述这些问题,其实大部分经销商老板还是明白的,但是问题是他们知道了问题的根结,但是却不能很好的解决或者不知道怎么解决。在这里结合实际的情况将提供一套专业的独特的解决方案给大家分享。解决方案一、 公司老板从自己开始重视仓库的管理,因为对于老板来说,公司的“现金库”和“实物库”管理非常的重要;二、 仓库的管理中“防火、防盗”等消防要重视;三、 公司仓管的“政审”要加强,也就是说要重视仓管这个职位,不要总以为业务员才是重要的;四、 绝对禁止无单发货、手工白条发货、不符合手续以及越权的借货等;五、 仓库的货物堆放要根据批次,堆放时要充分考虑到先进先出;六、 临界期、过期、不能二次销售、带退回供应商的商品要分开堆放,切忌不能和正常商品混合在一起,这样会导致仓库的混乱、库存不准、损耗加大以及仓库的整洁;七、 商品尽量根据品牌、类别分门别类堆放,这样将大大减少发货时间,当然公司的发货单或者配货单,必须要根据品牌和类别排序打印,否则则做不到减少发货时间;八、 实物仓库中的所有商品必须进行系统化管理,全部进入公司的系统进行统一管理,保护公司的宣传物料以及广告赠品;九、 规范收发货流程,必须制定一套规范化操作流程,并且严格执行操作流程,仓库的管理不能有随意性,否则你所有的努力将白费;十、 严格把控收货时的货龄检查以及包装完整度检查,切忌只要你将货物收到仓库,并且在对方送货单上签字确认,那么该商品的所有权将变成公司的,那么如果由于收货时候产生的一丝疏忽,都将是公司的损失;十一、 在发货期间,必须清晰的知道,我们的终端客户对货龄或者包装的要求,不能由于我们发货时的不专业,导致客户拒收,甚至由于订单缺送,导致我们的终端客户对公司进行缺送罚款,当然,这个必须公司有专业的系统,进行数据分析与监控,在打印配货单或者送货单的时候进行必要的提醒;十二、 仓库管理要想你的仓库盈亏数杜绝或者降低,那么频繁的核对实物库存这个很重要,一般我们是要做到:每天对当日有动销的商品进行核对,每周根据品牌进行库存核对,每月全面盘点一次。要做到这点,公司要对仓库管理员进行必要的装备配备,使用仓库扫描PDA设备,能明显的降低仓管的工作压力,快速盘点,快速得到盈亏数据;十三、 引进专业的“供应商管理专用软件”确保公司的所有员工的工作职责明确,执行到位;十四、 不管公司的大与小,也不分公司的类型,《供应商内部标准化管理》已经是必须的,也是迫切的。十五、如果资金允许,在仓库引进条码扫描管理功能,对于仓库发货商品,采用先配货-&扫描-&打正式出库单 模式进行,这样可以100%控制仓库‘划单’现象,并可以提高发货的正确率,杜绝错发、漏发、少发、多发现象。仓库管理方案要适合企业的实际情况,适合你的才是最好的!
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!_CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!_反对反对_新浪博客
我的图书馆
_CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!_反对反对_新浪博客
_CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
( 15:00:46)
在不同的模块分配的内存,释放的时候会出现此问题,而此问题,只在Debug模式会提示,Release模式不会提示。但不提示并不代表没有错误,一定要解决之。解决的方法是:在哪个模块分配的内存,就在哪个模块释放。
这个错误有两种可能:
一.释放的问题
1,内存不能跨模块分配和释放,模块分配的内存必须由该模块自己来释放。应该在DLL中再加一个方法,比如MemRelease,主程序调用这个方法来释放内存。
2,就是绕过new和,用GlobalAlloc()和GlobalFree()的方法
这个问题有两种情况:
1.链接外部lib出错:当前是模式,但工程属性-&Configureation
Properties-&Linker-&Input-&Additional Dependencies
中的链接库用的却是Release版本的,这个要仔细检查才行。相同道理,Release的模式下也有错用Debug链接库的问题。
2.ruantime Linbrary 方式选择错误:工程属性-&Configureation
Properties-&C/C++-&Code Generation-&Runtime
Library中的选项有可能与当前的编译方式不符。比如当前是Release模式却选择了Multi-threaded Debug DLL
(/MDd),相反当前是Debug模式却选择的是Multi-threaded DLL (/MD)。
今天遇到了这个assert,发现是dll中的一个局部vector释放的时候报的,这个vector是在dll中定义的,然后实在exe中分配的空间(通过引用传参数,然后调用push_back方法),这样,vector释放的时候它会发现dll正在释放一个不是由dll分配的内存,所以就会出此断言,一个临时的解决方案是,在dll中分配,可以通过vector的reserve方法来实现,当然,更好的解决方法是上层避免这种用法
还有在使用mfc时也遇到过这个问题,
mfc主程序中引用了一个dll,在dll中动态分配了一个对象,然后在主程序中释放,就会出现问题,是由于程序是静态依赖mfc运行时库的,这样在释放的时候,只查找主程序所在的堆空间,应用程序就认为释放了一个不再堆列表中的地址,而改为动态依赖mfc,程序才会查找依赖的dll中的堆列表,所以就没有问题了
从CrtIsValidHeapPointer的实现代码处我们可以得知,这个函数不仅检查了空指针的情况,更重要的是检查了指针地址的有效性。
我遇到的问题:
释放内存时,弹出assert,报错的函数就是上面提到的这个:CrtIsValidHeapPointer。
可是为什么会报错呢?CrtIsValidHeapPointer的注释上说明了情况:如果要释放的内存地址不是在当前控制的堆的地址范围内,也会报这样的错误。
问题分析:
1、我的实现是在exe中调用dll的一个方法,这个方法里面里面会分配若干内存,并将数据拷贝到新分配的内存中,传递出去;之后我会在exe中对这部分内存进行释放。
2、同一个进程,难道还有两个堆?如果你的工程Runtime
Library选择的是MT(使应用程序使用运行时库的多线程静态版本)类型,那么,是的,确实是这样,dll和exe是分别的两个堆。
3、也就是说,dll中分配的内存只能在dll中进行释放,否则CrtIsValidHeapPointer函数就会报错
起初觉得怎么这样呢?但考虑到不用dll的实现者是不一样的,那么他本身的选择的运行时库的链接方式也可能不一样,非要把他们都放在一个堆上操作反而会使问题变得复杂。CRT的这种处理确实更为合理。
解决方法:
既然谁分配谁释放,而我要分配的内存大小只有dll自己知道,我只好将分配内存的事情放在了dll中,然后dll再提供一个释放内存的方法。类似:
1、allocAndGetData(CData**
ppData);&&& //
我不喜欢这个函数名
2、freeData(*pData);
_CrtIsValidHeapPointer()在Debug模式下测试一个地址在本地的堆内存中,如果采用共享的方式链接C运行时库那么不会出现什么问题,但是如果采用静态的方式链接C运行时库,那么调用该DLL中的函数时就可能出现问题。提示一个错误.
例如:有两个DLL文件 a.dll ,b.dll 且a.dll采用静态的方式链接C运行时库。
如果 a.dll 中导出一个函数 CString aFun(),按值返回一个字符串。
如果 b.dll 中调用该函数如 CString str=aFun();
b.dll调试运行时将出现错误,提示_CrtIsValidHeapPointer()出错.
在MSDN中查找该函数说明知,当一个DLL采用静态的方式链接到C运行时库时,会创建一个相对于该DLL的堆(Heap),而如果采用共享的方式链接到C运行时库的时候则使用的是应用程序的堆内存。而_CrtIsValidHeapPointer()在
DEBug模式下将确保传入的地址在本地的堆内存中,这样问题就明显了:
a.dll采用静态链接C运行时库,所以会创建一个相对于该DLL的堆内存,这样a.dll中分配的临时变量均在该堆中分配。
再看a.dll中的函数aFun()以值的方式返回了一个字符串,执行到return语句时会创建一个临时的变量作为返回,但此临时变量内存却在a.dll的堆内存中,当在b.dll中调用时,语句CString
str=aFun();完成时该临时变量的CString析构函数被调用,会释放内存空间,但此时_CrtIsValidHeapPointer()检测到该内存地址不在本地的堆内存中,产生一个错误。但忽略该错误程序有时对正确运行。
解决的办法是将a.ll采用共享的方式链接到C运行时库。
这个错误花了很长时间才找出来,哈哈。。。。
这是因为dll拥有一个独立于应用程序(调用它的exe)的本地堆,调用过后dll占用的空间即被释放,先前new的内存地址即无效,那么解决此问题时要将dll文件中动态申请内存的时候使用HeapCreate函数而不能使用new操作符,具体说明详见MSDN,以下网址可供参考:
问题就出在红色的地方,自定义了一个类
将上面的语句改为
ColHistogram &pMyColH
pMyColHist = new ColH
就可以了,不过现在也不知道为什么
(MSDN)中的这段话
The _CrtIsValidHeapPointer function is used to ensure that a
specific memory address is within the local heap. The “local” heap
refers to the heap created and managed by a particular instance of
the C run-time library. If a dynamically linked library (DLL)
contains a static link to the run-time library, then it has its own
instance of the run-time heap, and therefore its own heap,
independent of the application’s local heap. When _DEBUG is not
defined, calls to _CrtIsValidHeapPointer are removed during
preprocessing.
看了这段话稍微觉得有点意思了,我在程序中自己申请了本地堆,也有要生成动态连接库的DIB类,要连接c运行库,那么我的ColHistogram的实例必须动态生成,因为它在c运行库中没有对应的堆。比如我添加Cstring
程序就不会有问题,但是我只知道CString是系统定义的,和c运行库有什么关系我就不清楚了。如果静态链接C运行库,那么,dll就要拥有一个独立于应用程序(调用它的exe)的本地堆(但是我的程序没有),如果没有定义_DEBUG,那么_CrtIsValidHeapPointer将被预处理器移除。大概就是这个样子,上面所说的很多东西我都不确定,只是现在的一种解释。
还有dbgheap.c文件似乎是在dll里,还没有办法看
只是把 调用程序 和 程序库 都编译成release就不会出现这个问题。
本质参考:
[http://topic.csdn.net/u//cc675daa-0ab2--98f3dd717439.html]
1,内存不能跨模块分配和释放,模块分配的内存必须由该模块自己来释放。应该在DLL中再加一个方法,比如MemRelease,主程序调用这个方法来释放内存。
2,就是绕过new和delete,用GlobalAlloc()和GlobalFree()的方法
自己:使用opencv 2.0 peopledetect.cpp 时,Debug版本出现该问题,通过更改
C/C++配置运行时库多线程调试 DLL (/MDd) 解决了问题。
奇怪的错误,坑死个人啊!!当C++/CLI程序引用了native
lib顺利编译之后,程序启动有可能出现以下错误:
这是ms的一个已知bug,原因:
The reason why you get this
error is that a winforms application has a managed entry point. The
initialization of the native global objects is done by the CRT (C
RunTime) startup routine. Since in this case there is no CRT
startup routine the MyBoard global object fails to initialize
correctly.
IDE is specific the entry of
ManagedApp as "main". However, using "main" will bypass a lot of
CRT's startup initialization.
解决方法:
右键点击项目---&properties---&link---&advanced
把Entry Point从main改为
"?mainCRTStartupStrArray@@$$FYMHP$01AP$AAVString@System@@@Z"
That should re-enable the CRT
startup code which initializes the internal CRT variables.That
symbol is really the mangled name for "int __clrcall
mainCRTStartupStrArray(cli::array^)".
malloc/free
malloc/free是C和C++语言的标准库函数, 可以被覆盖, 需要头文件库函数支持,
不在编译器控制范围之内, 不能够执行构造函数和析构函数的任务
malloc标准库函数的作用:分配动态堆内存
free标准库函数的作用:释放动态堆内存
用malloc分配的一块内存, 你要用指针访问并且要通过移动指针来访问内存数据
malloc只认字节数, 不管数据类型, 只能返回一个void*,
程序员要把void*强制类型转换成相应的指针类型,
同时还要用 if (NULL != ...) 来判断申请内存空间是否成功
&&&&&&&&&&&&&&&&&&&&&&&&&&&
new/delete
new/delete是C++的操作符, 是保留字, 可以被重载, 不需要头文件支持,
在编译器控制范围之内, 能够执行构造函数和析构函数的任务
new操作符的作用:分配动态堆内存、初始化对象(调用构造函数)
delete操作符的作用:清理对象(调用析构函数)、释放动态堆内存
用new创建的对象, 你可以用成员函数访问, 不用直接访问它的地址空间。
new可以认为是malloc加构造函数的执行, new出来的指针是直接带类型信息的, 不用进行强制类型转换
&&&&&&&&&&&&&&&&&&&&&&&&&
malloc/free 和 new/delete 的联系与区别
对于基本数据类型来说, 由于不像“对象”那样有构造与析构的过程,所以对它们而言,
malloc/free 和 new/delete是等价的
既然new/delete的功能完全覆盖了malloc/free,
为什么C++不把malloc/free淘汰出局呢?
因为C++程序经常要调用C函数, 而C程序只能用malloc/free分配和释放动态堆内存
内存泄漏对于malloc或者new都可以检查出来的, 区别在于new可以指明是那个文件的那一行, 而malloc没有这些信息
如果用free释放“new创建的动态对象”, 那么该对象因无法执行析构函数而可能导致程序出错。
如果用delete释放“malloc申请的动态内存”, 理论上讲程序不会出错, 但是该程序的可读性很差。
所以new/delete必须配对使用, malloc/free也一样。
&&&&&&&&&&&&&&&&&&&&&&&&&&
Visual C++ 6.0中的malloc/free 和 new/delete
int* p = (int*)malloc(5 * sizeof(int));
void* __cdecl malloc(size_t nSize)
void* res = _nh_malloc_dbg(nSize, _newmode, _NORMAL_BLOCK, NULL,
void* __cdecl _nh_malloc_dbg(size_t nSize, int nhFlag, int
nBlockUse, const char * szFileName, int nLine)
&&&&&&&&&&&
_mlock(_HEAP_LOCK);
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&&&&&
pvBlk = _heap_alloc_dbg(nSize, nBlockUse, szFileName,
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&
&&&&&&&&&&&&&&&
_munlock(_HEAP_LOCK);
&&&&&&&&&&&
&&&&&&&&&&&
if (pvBlk || nhFlag == 0)
&&&&&&&&&&&&&&&
return pvB
void* __cdecl _heap_alloc_dbg(size_t nSize, int nBlockUse, const
char * szFileName, int nLine)
pHead = (_CrtMemBlockHeader*)_heap_alloc_base(blockSize);
&// 在你分配的内存后面加4个256(即: 4个FD), 在释放内存时,
会以这4个FD作为内存界限的标志
&// _bNoMansLandFill的值是253,
nNoMansLandSize的值是4
memset((void*)pHead-&gap, _bNoMansLandFill,
nNoMansLandSize);
memset((void*)(pbData(pHead) + nSize), _bNoMansLandFill,
nNoMansLandSize);
memset((void*)pbData(pHead), _bCleanLandFill, nSize);
return (void*)pbData(pHead);
void* __cdecl _heap_alloc_base(size_t size)
return HeapAlloc(_crtheap, 0, size); // HeapAlloc函数是微软内部API,
用于分配堆内存
void __cdecl free(void * pUserData)
_free_dbg(pUserData, _NORMAL_BLOCK);
void __cdecl _free_dbg(void* pUserData, int nBlockUse)
_ASSERTE(_CrtIsValidHeapPointer(pUserData));
&// _bNoMansLandFill的值是253,
nNoMansLandSize的值是4
&CheckBytes(pHead-&gap, _bNoMansLandFill,
nNoMansLandSize);
CheckBytes(pbData(pHead) + pHead-&nDataSize, _bNoMansLandFill,
nNoMansLandSize);
memset(pHead, _bDeadLandFill, sizeof(_CrtMemBlockHeader) +
pHead-&nDataSize + nNoMansLandSize);
_free_base(pHead);
int __cdecl _CrtIsValidHeapPointer(const void* pUserData)
&return HeapValidate(_crtheap, 0,
pHdr(pUserData)); // HeapValidate函数是微软内部API, 用于验证指定堆的有效性
static int __cdecl CheckBytes(unsigned char* pb, unsigned char
bCheck, size_t nSize) // bCheck的值是253, nSize的值是4
int bOkay = TRUE;
while (nSize--)
&&&&&&&&&&&
if (*pb++ != bCheck) // 检查你分配的内存后面是否有4个256(即: 4个FD), 如果没有,
就说明有错误
&&&&&&&&&&&&&&&
bOkay = FALSE;
return bO // 检查无误, 返回TRUE
void __cdecl _free_base(void* pBlock)
PHEADER pH
if (pBlock == NULL)
&&&&&&&&&&&
HeapFree(_crtheap, 0, pBlock); // 释放一个内存块,
这个内存块是用HeapAlloc或HeapReAlloc分配的
int* a = new int[6];
void* operator new(unsigned int cb)
&&& void* res =
_nh_malloc(cb, 1);
&&& return
void* __cdecl _nh_malloc(size_t nSize, int nhFlag)
return _nh_malloc_dbg(nSize, nhFlag, _NORMAL_BLOCK, NULL,
void operator delete(void* pUserData)
_CrtMemBlockHeader * pH
if (pUserData == NULL)
&&&&&&&&&&&
_mlock(_HEAP_LOCK);
pHead = pHdr(pUserData);
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead-&nBlockUse));
_free_dbg(pUserData, pHead-&nBlockUse);
_munlock(_HEAP_LOCK);
class Person
&Person() { a = 1; b = 2.0; c = 'f'; }
&int GetA() { }
&double GetB() { }
&char GetC() { }
int main()
&Person* p = new Person();
&return 0;
Person* p = new Person();这句代码先调用
void* operator new(unsigned int cb)
&&& void* res =
_nh_malloc(cb, 1);
&&& return
后调用Person() { a = 1; b = 2.0; c = 'f'; }
这句代码调用
void operator delete(void* pUserData)
_CrtMemBlockHeader * pH
if (pUserData == NULL)
&&&&&&&&&&&
_mlock(_HEAP_LOCK);
pHead = pHdr(pUserData);
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead-&nBlockUse));
_free_dbg(pUserData, pHead-&nBlockUse);
_munlock(_HEAP_LOCK);
int main()
&char* p =
&return 0;
Debug调试程序:
char* p = 这句代码使p的内容变成0x00382DE0
00382DE0&& CD FD FD FD
分析: CD是帮char占一个字节的位置, 4个FD作为内存界限的标志
cin && 这句代码调用 istream& istream::operator&&(char*
如果你输入a[Enter], 则内存如下:
00382DE0&& 61 00 FD FD
FD&&分析: Ox61是字符'a'的ASCII码,
0x00是operator&&加的'\0', 因为char* s是字符串, 要以'\0'结尾, p是实参,
cout && 这句代码调用 ostream&
ostream::operator&&(const char* s)
执行完这句代码后, 屏幕并没有输出任何信息
这句代码调用 void operator delete(void* pUserData)
在void __cdecl _free_dbg(void* pUserData, int
nBlockUse)的第二个CheckBytes代码里面出现问题Debug Error,
选择“忽略”错误, 最终屏幕还是没有输出任何信息
Debug直接执行程序:
如果你输入a[Enter], 则会出现问题Debug Error
Release直接执行程序:
如果你输入a[Enter], 则会很好地输出a
如果你输入abcdefghijk[Enter], 则会很好地输出abcdefghijk
_CrtIsValidHeapPointer(pUserData)& 问题解决
在project setting里link里将general debug
info去掉就可以了,不过根本问题是有悬空指针
所有的lib都要和主程序版本一样,如果是release,都是release,主程序是debug版本则无所谓
在VC++2005中使用Pwlib和Opal库,界面使用WinForm进行开发,编译选项为 /clr
编译、链接都没有问题,但启动程序时,出现运行时错误:
在网上搜了很久,发现很少有人提到该问题的解决办法,后来看到微软的论坛上,有人提出过这个bug,详情请看我的另外一篇文章:
原来导致该问题的原因是:
The reason why
you get this error is that a winforms application has a managed
entry point. The initialization of the native global objects is
done by the CRT (C RunTime) startup routine. Since in this case
there is no CRT startup routine the MyBoard global object fails to
initialize correctly.
VC++开发组的人给出了一种折中的办法,
<font color="#. Set Linker\Advanced\Entry Point to "" (empty
2. Set Linker\System\Subsystem to Not Set
Step 1: Makes
sure that the CRT startup code is invoked. This is because, if no
entry point is specified, the linker will automatically use
mainCRTStartup, which is defined in the CRT libraries.
mainCRTStartup will make sure that the global object is initialized
correctly.
Step 2: Makes sure that the linker
will look for the symbol “main”. The linker looks for “main”
because mainCRTStartup calls main() in its body. The default option
for a Winforms application is Subsystem:Windows and this makes the
linker look for WinMain().
虽然程序可以正常启动,但是却会在程序显示Winform的同时,出现一个console窗口,很是不爽。
不服输的我,继续到处找资料,查找了几乎网上所有的资源,在微软的官方文档中,该问题被定义为 load
lock,即CLI和CRT的初始化死锁问题,
详见 我的另外一篇文章:
但是在该文档中提到的几种解决方法,经过测试,发现对我的这个问题均无作用。
后来找到在VC++2003中的解决初始化问题的文章,
详见 我的另外一篇文章:
该文章详细介绍了VC++2003中的臭名昭著的load lock问题,并给出了解决办法,即自己写dll的初始化函数。
感觉到好像有了希望!!
根据文章介绍的另外一篇文章:
详见我的另外一篇文章:
我进行了大量测试,最后发现,VC++2005中的load
lock问题,确实已经简化了很多,即已经确定化,最后我终于找到了解决方案:
解决方案:
在项目中添加CPP文件,其中定义一个托管类,其成员函数负责手动调用CRT的初始化。
注意,项目中只要有该CPP文件即可,不需要生成对象或者调用其成员函数。
该文件名称为ManagedWrapper.cpp,定义如下:
ManagedWrapper.cpp
This code verifies that DllMain is not called
by the Loader
automatically when linked with /noentry. It
also checks some
functions that the CRT
initializes.
&&/SPAN&windows.h&
&&/SPAN&stdio.h&
&&/SPAN&string.h&
&&/SPAN&stdlib.h&
&&/SPAN&math.h&
"_vcclrit.h"
&&/SPAN&mscorlib.dll&
ref class ManagedWrapper
static int minitialize()
int retval = 0;
__crt_dll_initialize();
catch(System::Exception^ e)
Console::WriteLine(e);
mterminate()
int retval = 0;
__crt_dll_terminate();
catch(System::Exception^ e)
Console::WriteLine(e);
经过测试,一切OK!!!!
太爽了,终于可以抛开MFC那笨拙的界面开发工具!!
我现在可以充分利用Winform的快速界面开发功能,底层调用Pwli和Opal来开发视频会议了!
呵呵,我已经连续3天没有睡觉了,今晚终于可以做个好梦了!!
malloc和free在教材里不知讲了多少,今天实际用到一处,就出问题了。
案发现场是我用VC++在WINXP下编程,先看这一段代码
&&&&BYTE&&&&*pBuffer;
&&&&pBuffer
= (BYTE *)malloc(64);
&&&&pBuffer
= pBuffer + 32;
&&&&free(pBuffer);
&&&&pBuffer
}&&//第一段
先声明一个指针,然后分配64字节给它。操作指针向后移动32字节,最后把这个指针free掉并设为NULL。这样虽然操作时的数据还留在内存区域里,但已经没有指针指向该区域,数据可以被后面的程序覆盖了。看起来没错吧?恩恩好象是没错,
抓了三个同事来问,全票通过.&&但在实际上呢,
运行时会跳出这个警告:
而如果把代码改成
&&&&BYTE&&&&*pBuffer;
&&&&pBuffer
= (BYTE *)malloc(64);
&&&&pBuffer
= pBuffer + 32;
&&&&pBuffer = pBuffer
-32;&&&&free(pBuffer);
&&&&pBuffer
}&&//第二段代码
就没错了。李博士的解释是:malloc的时候系统创建了一个链表之类的东西,里面包含了起始地址和长度;而free的时候根据参数中的指针进行判断,如果该指针符合链表中某一节的起始地址,那么就把这一节free掉,如果去free一个不在链表中的地址,就出错啦。
比较好的处理方式是这样
&&&&BYTE&&&&*pBuffer;
&&&&BYTE&&&&*pByteP
&&&&pBuffer
= (BYTE *)malloc(64);
&&&&pBytePtr
&&&&pBytePtr
= pBytePtr + 32;
&&&&free(pBuffer);
&&&&pBuffer
&&&&pBytePtr
}&&//第三段代码
即保留malloc时候的初始地址,然后赋给另外一个临时指针。操作时使用后者。free的时候把保留的起始指针free掉,而临时指针只是个变量,置空就可以了。
文章到这里似乎就应该写完了,不过由于johnathan的帮忙, 突然有了下文。
注意警告框中的_CrtIsValidHeapPointer,在MSDN上查到这个函数的说明为:
Verifies that a specified pointer is in the local heap (debug
version only).
int _CrtIsValidHeapPointer(const void *userData);
Parameter:
userData&&Pointer to the beginning of an
allocated memory block.
Return Value:
_CrtIsValidHeapPointer returns TRUE if the specified pointer is in
the local heap. Otherwise, the function returns FALSE.
也就是说仅在debug版本中检查free参数是否为the beginning of an allocated memroy
那么就编译一个release版本,果然,运行通过, 没弹出什么警告或错误。但运行通过不等于正常无误,
&博士认为这就是无声无息导致内存泄露的罪魁祸首.
即使release版里面也应该free起始地址.
那么结论就是:free掉非malloc起始地址的指针,在debug版本中会出错警告,而在release版本中不会弹出警告但仍然是有错的。所以,还是推荐使用第三段代码的用法
检查指针有效性
下面的示例使用 _CrtIsValidPointer 验证给定的内存范围对于读或写是否有效。
_ASSERTE(_CrtIsValidPointer( address, size, TRUE );
下面的示例使用 _CrtIsValidHeapPointer 验证指针指向本地堆(由 C 运行时库的这个实例创建和管理的堆;DLL
可以有它自己的库实例,因而也可以有它自己的、位于应用程序堆之外的堆)中的内存。该断言不仅捕捉空地址或超出边界的地址,还捕捉指向静态变量、堆栈变量和其他任何非本地内存的指针。
_ASSERTE(_CrtIsValidPointer( myData );
//从CSDN.NET
_CrtIsValidHeapPointer(pUserData)的问题:
&_CrtIsValidHeapPointer确认内存地址在本地堆。……如果静态链接C运行库,那么,dll拥有一个独立于应用程序(调用它的
exe)的本地堆。(所以你上面的程序会Debug&&
Assertion&&
Failed),如果没有定义_DEBUG,那么_CrtIsValidHeapPointer将被预处理器移除。&&&
如果是:Debug&&
Assertion&&
Failed!& 解决的方法有二:
& 1、动态链接C运行库:
2、设置统一的Debug/Release版本(比如全部设置为release版本);(ok)
&&如果“Assertion&&
Failed”的话,估计程序是会出问题的.
The & _CrtIsValidHeapPointer &
function & is & used
& to & ensure &
that & a & specific
& memory & address
& is & within &
the & local & heap.
& The & “local”
& heap & refers
& to & the &
heap & created & and
& managed & by &
a & particular & instance
& of & the & C
& run-time & library.
& If & a &
dynamically & linked & library
& (DLL) & contains
& a & static &
link & to & the
& run-time & library,
& then & it &
has & its & own
& instance & of
& the & run-time
& heap, & and &
therefore & its & own
& heap, & independent
& of & the &
application’s & local & heap.
& When & _DEBUG
& is & not &
defined, & calls & to
& _CrtIsValidHeapPointer & are
& removed & during
& preprocessing.
代码一气呵成,但运行的时候会出现_CrtIsValidHeapPointer的异常,跟进去调了一上午的Bug,终于搞定
跟踪定位到
_CrtIsValidHeapPointer ,注意到 g 8h"@dbgheap.c 文件中
_CrtIsValidHeapPointer 处注释:
&_ASSERTE(_CrtIsValidHeapPointer(pUserData));
  大概是因为 dll 如果静态链接了运行时库,dll 就会拥有独立于应用程序堆(也称作local heap)的运行时堆实例。此时在
dll 外部就不能访问此 local heap,所以也就有上面所出现的异常啦。MSDN 中也有介绍:
  The _CrtIsValidHeapPointer function is used to ensure that a
specific memory address is within the local heap. The local heap
refers to the heap created and managed by a particular instance of
the C run-time library. If a dynamic-link library (DLL) contains a
static link to the run-time library, it has its own instance of the
run-time heap, and therefore its own heap, independent of the
application's local heap. When _DEBUG is not defined, calls to
_CrtIsValidHeapPointer are removed during
preprocessing.
程序崩溃在当析构一个带有vector成员函数对象的时候,在析构vector时,会出现这个错误,大致原因是因为析构的时候找不到vector分配的空间
一行一行查看代码发现,对象里面的points2,
status等vector变量是在calcOpticalFlowPyrLK(img1, img2, points1, points2,
status, similarity, window_size, level, term_criteria, lambda, 0);
函数中分配的,即opencv的dll,所以当对象进行析构的时候,因为不能访问此local
heap所以会有异常崩溃。
解决方法:
在调用opencv的函数之前,自己进行空间的分配
喜欢该文的人也喜欢

我要回帖

更多关于 迅雷任务出错解决方法 的文章

 

随机推荐