精华内容
下载资源
问答
  • 在使用Visual Studio过程中,有时候会遇到每次启动程序时,都需要重新编译...后来在StackOverflow上找到了寻找根本原因的方法(然而该答案居然不是排名第一): http://stackoverflow.com/questions/1480008/why...

    在使用Visual Studio的过程中,有时候会遇到每次启动程序时,都需要重新编译一次的问题,使用重新生成解决方案、清理解决方案均不能解决问题。在网上搜了一下,发现可能引起该问题的原因有很多,并没有一个好的总结。后来在StackOverflow上找到了寻找根本原因的方法(然而该答案居然不是排名第一):

    http://stackoverflow.com/questions/1480008/why-does-vs-have-to-rebuild-all-of-my-projects-every-time-i-hit-play

    在中文Visual Studio里就是工具->选项->项目与解决方案->生成并运行:

    选择为“诊断”,这样在生成时,就可以在输出列表的开头,找到究竟是哪个文件使编译器判断编译结果不是最新的。

    转载于:https://www.cnblogs.com/huhewei/p/5904226.html

    展开全文
  • 在不同模块分配内存,释放时候会出现此问题,而此问题,只在Debug模式会提示,Release模式不会提示。但不提示并不代表没有错误,一定要解决之。解决方法是:在哪个模块分配内存,就在哪个模块释放。 这个...

    在不同的模块分配的内存,释放的时候会出现此问题,而此问题,只在Debug模式会提示,Release模式不会提示。但不提示并不代表没有错误,一定要解决之。解决的方法是:在哪个模块分配的内存,就在哪个模块释放。

     

    这个错误有两种可能:

    一.释放的问题

    1,内存不能跨模块分配和释放,模块分配的内存必须由该模块自己来释放。应该在DLL中再加一个方法,比如MemRelease,主程序调用这个方法来释放内存。

    2,就是绕过new和delete,用GlobalAlloc()和GlobalFree()的方法
    二.动态链接库的问题

    这个问题有两种情况:

    1.链接外部lib出错:当前是Debug模式,但工程属性->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  pMyColHist;
    pMyColHist = new ColHistogram;

    就可以了,不过现在也不知道为什么

    (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 str;程序就不会有问题,但是我只知道CString是系统定义的,和c运行库有什么关系我就不清楚了。如果静态链接C运行库,那么,dll就要拥有一个独立于应用程序(调用它的exe)的本地堆(但是我的程序没有),如果没有定义_DEBUG,那么_CrtIsValidHeapPointer将被预处理器移除。大概就是这个样子,上面所说的很多东西我都不确定,只是现在的一种解释。

    还有dbgheap.c文件似乎是在dll里,还没有办法看

     
     
    只是把 调用程序 和 程序库 都编译成release就不会出现这个问题。
    本质参考: [http://topic.csdn.net/u/20071116/09/cc675daa-0ab2-4952-99d0-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, 0);

            return res;
    }

    void* __cdecl _nh_malloc_dbg(size_t nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine)
    {
            void* pvBlk;

            for (;;)
            {
                _mlock(_HEAP_LOCK);

                __try
                {
                    pvBlk = _heap_alloc_dbg(nSize, nBlockUse, szFileName, nLine);
                }
                __finally
                {
                    _munlock(_HEAP_LOCK);
                }

                if (pvBlk || nhFlag == 0)
                    return pvBlk;
            }
    }

    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, 用于分配堆内存
    }

    free(p);

    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 bOkay; // 检查无误, 返回TRUE
    }

    void __cdecl _free_base(void* pBlock)
    {
            PHEADER pHeader;

            if (pBlock == NULL)
                return;

            HeapFree(_crtheap, 0, pBlock); // 释放一个内存块, 这个内存块是用HeapAlloc或HeapReAlloc分配的
    }

    int* a = new int[6];

    void* operator new(unsigned int cb)
    {
        void* res = _nh_malloc(cb, 1);

        return res;
    }

    void* __cdecl _nh_malloc(size_t nSize, int nhFlag)
    {
            return _nh_malloc_dbg(nSize, nhFlag, _NORMAL_BLOCK, NULL, 0);
    }

    delete a;

    void operator delete(void* pUserData)
    {
            _CrtMemBlockHeader * pHead;

            if (pUserData == NULL)
                return;

            _mlock(_HEAP_LOCK);

            pHead = pHdr(pUserData);

            _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));

            _free_dbg(pUserData, pHead->nBlockUse);

            _munlock(_HEAP_LOCK);
    }

    class Person
    {
    public:
     Person() { a = 1; b = 2.0; c = 'f'; }
     int GetA() { return a; }
     double GetB() { return b; }
     char GetC() { return c; }
    private:
     int a;
     double b;
     char c;
    };

    int main()
    {
     Person* p = new Person();

     delete p;

     return 0;
    }

    Person* p = new Person();这句代码先调用
    void* operator new(unsigned int cb)
    {
        void* res = _nh_malloc(cb, 1);

        return res;
    }
    后调用Person() { a = 1; b = 2.0; c = 'f'; }

    delete p;这句代码调用
    void operator delete(void* pUserData)
    {
            _CrtMemBlockHeader * pHead;

            if (pUserData == NULL)
                return;

            _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 = new char;

     cin >> p;
     cout << p;
     delete p;

     return 0;
    }

    Debug调试程序:
    char* p = new char; 这句代码使p的内容变成0x00382DE0
    00382DE0   CD FD FD FD FD
    分析: CD是帮char占一个字节的位置, 4个FD作为内存界限的标志

    cin >> p; 这句代码调用 istream& istream::operator>>(char* s)
    如果你输入a[Enter], 则内存如下:
    00382DE0   61 00 FD FD FD  
    分析: Ox61是字符'a'的ASCII码, 0x00是operator>>加的'\0', 因为char* s是字符串, 要以'\0'结尾, p是实参, s是形参

    cout << p; 这句代码调用 ostream& ostream::operator<<(const char* s)
    执行完这句代码后, 屏幕并没有输出任何信息

    delete p; 这句代码调用 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,详情请看我的另外一篇文章:

    _CrtIsValidHeapPointer
    http://www.cnblogs.com/sunrack/articles/588115.html

    原来导致该问题的原因是:

    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++开发组的人给出了一种折中的办法,

    1. Set Linker\Advanced\Entry Point to "" (empty string)
    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的初始化死锁问题,
    详见 我的另外一篇文章:

    Initialization of Mixed Assemblies
    http://www.cnblogs.com/sunrack/articles/592408.html

    但是在该文档中提到的几种解决方法,经过测试,发现对我的这个问题均无作用。

    后来找到在VC++2003中的解决初始化问题的文章,

    详见 我的另外一篇文章:

    Persisting View State Update, Using Managed Extensions in a DLL
    http://www.cnblogs.com/sunrack/articles/593807.html

    该文章详细介绍了VC++2003中的臭名昭著的load lock问题,并给出了解决办法,即自己写dll的初始化函数。

    感觉到好像有了希望!!


    根据文章介绍的另外一篇文章:
    详见我的另外一篇文章:

    Converting Managed Extensions for C++ Projects from Pure Intermediate Language to Mixed Mode
    http://www.cnblogs.com/sunrack/articles/593847.html

    我进行了大量测试,最后发现,VC++2005中的load lock问题,确实已经简化了很多,即已经确定化,最后我终于找到了解决方案:

    解决方案:

    在项目中添加CPP文件,其中定义一个托管类,其成员函数负责手动调用CRT的初始化。

    注意,项目中只要有该CPP文件即可,不需要生成对象或者调用其成员函数。

    该文件名称为ManagedWrapper.cpp,定义如下:

    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!// ManagedWrapper.cpp
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
    //
     This code verifies that DllMain is not called by the Loader
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
    //
     automatically when linked with /noentry. It also checks some
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
    // functions that the CRT initializes.

    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!

    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!#include
     <</SPAN>windows.h>
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!#include
     <</SPAN>stdio.h>
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!#include
     <</SPAN>string.h>
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!#include
     <</SPAN>stdlib.h>
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!#include
     <</SPAN>math.h>
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!#include
     "_vcclrit.h"
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
    #
    using <</SPAN>mscorlib.dll>
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
    using namespace System;
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
    public ref class
     ManagedWrapper
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦! 
    {
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
    public
    :
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
     static int
     minitialize()
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦! 
    {
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
     int retval = 0
    ;
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
     try
     
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦! 
    {
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
     __crt_dll_initialize();
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦! 
    }
     
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
     catch(System::Exception^
     e)
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦! 
    {
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
     Console::WriteLine(e);
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
     retval
     = 1
    ;
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦! 
    }

    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
     return retval;
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦! 
    }

    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
     static int mterminate()
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦! 
    {
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
     int retval = 0
    ;
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
     try
     
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦! 
    {
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
     __crt_dll_terminate();
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦! 
    }
     
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
     catch(System::Exception^
     e)
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦! 
    {
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
     Console::WriteLine(e);
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
     retval
     = 1
    ;
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦! 
    }

    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦!
     return retval;
    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦! 
    }

    _CrtIsValidHeapPointer出错的解决方法,找到了根本原因啦! }
    ;

    经过测试,一切OK!!!!

    太爽了,终于可以抛开MFC那笨拙的界面开发工具!!
    我现在可以充分利用Winform的快速界面开发功能,底层调用Pwli和Opal来开发视频会议了!

    呵呵,我已经连续3天没有睡觉了,今晚终于可以做个好梦了!!

     
     
     
     

    malloc和free在教材里不知讲了多少,今天实际用到一处,就出问题了。

    案发现场是我用VC++在WINXP下编程,先看这一段代码
    {
        BYTE    *pBuffer;
        pBuffer = (BYTE *)malloc(64);
        pBuffer = pBuffer + 32;
        free(pBuffer);
        pBuffer = NULL;
     //第一段
    先声明一个指针,然后分配64字节给它。操作指针向后移动32字节,最后把这个指针free掉并设为NULL。这样虽然操作时的数据还留在内存区域里,但已经没有指针指向该区域,数据可以被后面的程序覆盖了。看起来没错吧?恩恩好象是没错, 抓了三个同事来问,全票通过.  
    但在实际上呢, 运行时会跳出这个警告:

    free指针时遭遇_CrtIsValidHeapPointer

    而如果把代码改成
    {
        BYTE    *pBuffer;
        pBuffer = (BYTE *)malloc(64);
        pBuffer = pBuffer + 32;
        
    pBuffer = pBuffer -32;
        free(pBuffer);
        pBuffer = NULL;
     
    //第二段代码
    就没错了。李博士的解释是:malloc的时候系统创建了一个链表之类的东西,里面包含了起始地址和长度;而free的时候根据参数中的指针进行判断,如果该指针符合链表中某一节的起始地址,那么就把这一节free掉,如果去free一个不在链表中的地址,就出错啦。

    比较好的处理方式是这样
    {
        BYTE    *pBuffer;
        BYTE    *pBytePtr;
        pBuffer = (BYTE *)malloc(64);
        pBytePtr = pBuffer;
        pBytePtr = pBytePtr + 32;
        free(pBuffer);
        pBuffer = NULL;
        pBytePtr = NULL;
     
    //第三段代码

    即保留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 block.

    那么就编译一个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的函数之前,自己进行空间的分配

    展开全文
  • 寻找问题原因的主要方法是头脑风暴会议,问题寻找的过程,也往往不会只通过一次或几次的头脑风暴就可以找到问题原因,我们要充分发挥团体的智慧,从各种不同的角度找出问题的所有潜在原因。在使用头脑风暴时候,结合...

    终于终于西蒙用小提琴拉了一首《小星星》,内牛满面啊!

    正文:

    在过程分析和数据分析的基础上,需要从多个方面,广泛寻找导致问题发生的潜在原因,这是一个群策群力的过程。寻找问题原因的主要方法是头脑风暴会议,问题寻找的过程,也往往不会只通过一次或几次的头脑风暴就可以找到问题原因,我们要充分发挥团体的智慧,从各种不同的角度找出问题的所有潜在原因。在使用头脑风暴时候,结合5W2H分析法,能够避免遗漏问题原因。

    5W2H分析

    5W2H是一种提问式的查找问题原因和解决措施的方法,它是以5W开头的英文单词和两个H开头的英文单词进行提问,从而发现解决问题的线索。其优点在于简单、方便、易于理解和使用,富有启发意义,目前被广泛应用于企业管理活动,对于决策和执行性的活动措施非常有帮助,并且有助于弥补考虑问题时的疏漏。

    以下是5W2H分析法的主要内容:

    WHEN 时间 什么时间完成?什么时机最合适?

    WHERE 地点 在哪里做?从哪里入手?

    WHO 谁? 由谁来承担?谁来完成?谁负责?

    WHAT 做什么? 目的是什么?内容是什么?做什么工作?

    WHY 为什么? 为什么这么做?理由何在?原因是什么?

    HOW 如何做? 如何提高效率?如何实施?方法怎样?

    HOW MUCH 做多少? 做到什么程度?数量如何?质量水平如何?

    “ ” 后的问题根据要分析的问题可以进行变化,具体问题具体分析。

     

    例如,我们使用该方法,对客户满意度下降问题进行分析:

    WHEN | 客户满意度最近在哪个时期下降最为明显?

    WHERE | 哪里的客户不满意?有没有地域特点?

    WHO | 是谁不满意?是都不满意还是个别群体不满意?是高端客户不满意还是普通客户不满意?

    WHAT | 不满意的内容有哪些?

    WHY | 为什么不满意?

    HOW | 如何才能让客户满意?

    HOW MUCH | 做到什么程度客户才能满意?做到什么程度能够符合 “质量/成本”效益原则?

     

    可以看出,通过使用5W2H分析法,可以准确清晰地表述问题,有效掌控事件的主骨架,从而有助于全面思考问题,避免在流程设计中遗漏事项。 

     

    当我们挖掘到的问题越来越多的时候,就需要理清这些原因之间的关系,使其脉络清晰,便于查找主要问题原因。这个时候我们引入因果图分析,因其外形像鱼骨头,也叫鱼骨图分析,是一种用于识别导致问题发生的根本原因,并对原因进行有效分类的工具。

     

    1、鱼骨图的作用

    鱼骨图的主要作用是提供了一个图形化,结构化的分析方法,根据问题特性,将与之关联的影响因素整理到一起,层次分明,条理清楚,从而便于理解各种因素之间的相互关系。

    ·鱼骨图能够聚焦于问题为什么会发生?使团队关注问题的原因,而不是问题的症状。

    ·鱼骨图能够集中于问题的实质内容,而不是问题的历史或不同的个人观点。

    ·鱼骨图能够辨识导致问题或情况的所有原因,并从中找到根本原因。

    ·鱼骨图能够分析导致问题的各个原因之间相互的关系。

    ·鱼骨图也为收集什么样的数据提供了指引。

     

    例如,近期网站上的客户投诉明显上升,客户满意度下降,通过头脑风暴会议共列举了13项潜在的问题原因:

    ·投递员服务质量差

    ·投递时间长

    ·未按约定的时间投递

    ·未提示客户验货

    ·初次投递不到未进行二次投递

    ·投递到单位收发室而非客户本人

    ·不支持POS刷卡付款

    ·POS只能刷借记卡

    ·不能跟踪订单投递状态

    ·产品质量差

    ·售后服务不到位

    ·产品功能与描述不符

    ·产品运输过程损坏较多。

    这些是我们通过头脑风暴找到的原因,实际上往往会比这复杂。但就这么多原因罗列到仪器,就已经让人感到眼花缭乱,影响客户满意度的因素竟然有这么多,到底哪些是主要因素呢?

    如下图,我们使用鱼骨图分析,从人员、设备、流程、产品四个维度去归纳梳理,会发现脉络非常清晰,令人有一种豁然开朗的感觉,这就是鱼骨图的优势所在。

     

    同事,鱼骨图也列出了数据测量的对象,可以从人员、设备、流程、产品几个方面去确定导致客户满意度下降的主要原因。

     

    ___________________________________________________________________

    写字不易,且读且珍惜,转载请注明出处:SimonK @http://www.cnblogs.com/simonk/

    更博时间:

    周一到周五每天一更,时间8:50-9:40之间

    周六/周日/法定节假日 不定期

    欢迎订阅!

    下节预报:鱼骨图的使用方法以及帕累托图

    ___________________________________________________________________

    转载于:https://www.cnblogs.com/simonk/p/3785219.html

    展开全文
  • 不是硬件问题,果然还是内核的问题。当然,虽然是内核缺陷,也完全不用改内核源码,只要配置一下内核选项就好了。 对比了瑞泰DEMO内核和我自己内核,发现了一个重要区别。 这是他版本: Linux version ...

    不是硬件问题,果然还是内核的问题。当然,虽然是内核的缺陷,也完全不用改内核源码,只要配置一下内核选项就好了。

    对比了瑞泰的DEMO内核和我自己的内核,发现了一个重要的区别。

    这是他的版本:

    Linux version 2.6.28-icetek (davinci@davinci-desktop) (gcc version 4.2.1 (CodeSourcery Sourcery G++ Lite 2007q3-51)) #2 Thu Jul 30 13:37:22 CST 2009

    他的启动日志里面:

    twl4030_usb twl4030_usb: Initialized TWL4030 USB module
    usbcore: registered new interface driver usbfs
    usbcore: registered new interface driver hub
    usbcore: registered new device driver usb
    musb_hdrc: version 6.0, musb-dma, host, debug=0
    musb_hdrc: USB Host mode controller at d80ab000 using DMA, IRQ 92
    musb_hdrc musb_hdrc: MUSB HDRC host driver
    musb_hdrc musb_hdrc: new USB bus registered, assigned bus number 1
    usb usb1: configuration #1 chosen from 1 choice
    hub 1-0:1.0: USB hub found
    hub 1-0:1.0: 1 port detected
    usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
    usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
    usb usb1: Product: MUSB HDRC host driver
    usb usb1: Manufacturer: Linux 2.6.28-icetek musb-hcd
    usb usb1: SerialNumber: musb_hdrc
    regulator: VMMC1: 1850 <--> 3150 mV normal standby
    regulator: VDAC: 1800 mV normal standby
    regulator: VUSB1V5: 1500 mV normal standby
    regulator: VUSB1V8: 1800 mV normal standby
    regulator: VUSB3V1: 3100 mV normal standby
    regulator: VSIM: 1800 <--> 3000 mV normal standby

    而我的版本:

    Linux version 2.6.28-icetek (root@dolphi-dev) (gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203) ) #1 Sat Feb 23 12:57:40 CST 2013

    (终于找到了这个版本的源码)

    启动日志里面:

    twl4030_usb twl4030_usb: Initialized TWL4030 USB module
    usbcore: registered new interface driver usbfs
    usbcore: registered new interface driver hub
    usbcore: registered new device driver usb
    musb_hdrc: version 6.0, musb-dma, otg (peripheral+host), debug=0
    musb_hdrc: USB OTG mode controller at d80ab000 using DMA, IRQ 92
    regulator: VMMC1: 1850 <--> 3150 mV normal standby
    regulator: VDAC: 1800 mV normal standby
    regulator: VUSB1V5: 1500 mV normal standby
    regulator: VUSB1V8: 1800 mV normal standby
    regulator: VUSB3V1: 3100 mV normal standby
    regulator: VSIM: 1800 <--> 3000 mV normal standby

    可以看出来,在USB控制器的模式上,demo用的是host,而我用的是otg模式。

    而且在beagle的资料上面说过,内核对otg模式的支持并不是很好。所以我之前出现的各种USB时好时坏,归其根本原因就在这里。就是要在内核配置里面指定USB控制器工作在host模式,怎么配置呢。就是在USB驱动的Driver Mode中选择USB Host模式就好啦。

    从此以后,就完全不存在什么时候插USB的问题,就是什么时候插都好的。

     

    转载于:https://www.cnblogs.com/dolphi/archive/2013/02/23/2923493.html

    展开全文
  • 根本原因分析(RCA)是一项结构化的问题处理法,用以逐步找出问题的根本原因并加以解决, 而不是仅仅关注问题的表征。这要求我们要透过冰山一角,找到隐藏在水下的部分。 当然,任何一个问题,如果我们刨根究底,不...
  • CMMI成功的根本原因是什么?

    千次阅读 2009-12-08 13:13:00
    随即,在林林种种的原因中,我找到了我认为最重要的原因:“企业文化与领导重视!”。昨天中午、晚上也都和其他朋友在深入讨论这个问题,越来越发现,这个结论正确性。 企业文化也许是一种说不清道不明东西,...
  • 5why法的关键所在:鼓励解决问题的人要努力避开主观或自负的假设和逻辑陷阱,从结果着手,沿着因果关系链条,顺藤摸瓜,直至找出原有问题的根本原因。 介绍 这种方法最初是由丰田佐吉提出的;后来,丰田汽车公司...
  • WampServer启动后,服务器状态显示为在线,但是图标为黄色,然后开始检查问题原因: 1.首先检查端口占用情况,httpd.conf中配置监听端口为Listen localhost:8088,通过netstat -ano|findstr “8088”,并未发现...
  • Oracle常见错误:ORA-01403 的根本原因和解决方案 根本原因:SELECT语句查询出来的结果为空,此时把查询出来的空值赋给2个变量,就出现了上面这个错误。ORA-01403: 未找到任何数据,报这个错误 通常都是SELECT INTO ...
  • 出现这种问题我看数据库里面也多了{dede:img text= …}所以应该是程序自动添加经过查找找到根本原因{dede:img text= …}办法
  • 根本原因是没有找到资源。 原因一 修改了web.xml但是没有重启tomcat服务器,因为它是把web.xml加载到内存,所以后面修改了也必须重启服务器才能获取到新配置servlet 原因二 检查servlet-mappingurl-...
  • 有时候会发生无线网络不稳的情况,时快时慢,偶尔还会发生掉线,可能你会抱怨连接不稳定和性能差劲,这样便会妨碍应用程序的使用,其实我们应该需要对无线网进行一定的诊断,这样才能找到问题的根本原因,从而解决。...
  • 有时候会发生无线网络不稳的情况,时快时慢,偶尔还会发生掉线,可能你会抱怨连接不稳定和性能差劲,这样便会妨碍应用程序的使用,其实我们应该需要对无线网进行一定的诊断,这样才能找到问题的根本原因,从而解决。...
  • 项目中出现问题总是难免,作为管理者需要注意是,这个问题是不是能够避免...Wiki中列出了很多具体实践技术,可能最简单就是"5个为什么",真正避免问题再次发生,找到根本原因是第一步,那就先试试问"5个为什
  • PM的价值,就在于解决产品发展过程中的各种阻碍。而解决这些阻碍,就要找到问题的根源,才能举一反三,有效避免产品开发失败。
  • 首先,先向大家道歉:上一篇关于finalize() timed out的博客误导了大家,当问题出现后,我们应该找到问题的根本原因,从根源上去解决。然而对于这个问题来说却不太容易实现,和其他问题不同,这类问题原因比较复杂,...
  • 找到线程不安全根源,就好像找到了一把万能钥匙,解开程序中任何线程不安全隐患。 12 二、分析 对于线程安全定义,《深入理解Java虚拟机:JVM高级特性与最佳实践》(P343)认为《Java Concurrency In ...
  • 根本的原因其实就是引用的问题,引用错了,然后VS在这上面提示又不够智能,所以大家被坑一次又一次 不过也许这只是原因之一,还会有其他的原因 第一种可能: 这种可能性很好排查,A项目所使用.net版本为3.5,B...
  • 在安装64位版本的office2013/2010/2007时,都遇到了这样的问题:”无法安装64位版本的Office,因为在您的PC上找到了以下32位程序“,出现这个问题的根本原因就是你曾经在电脑上安装过32位版本的office,但是在...
  • 根本的原因其实就是引用的问题,引用错了,然后VS在这上面提示又不够智能,所以大家被坑一次又一次 不过也许这只是原因之一,还会有其他的原因 第一种可能: 这种可能性很好排查,A项目所使用.net版本为3.5,...
  • 但经过我多次检查和敲打,我否决了这种情况,后来我仔细琢磨了一下“No such file or directory"这句话,发现并不是头文件出现了问题,而是根本就找不到该头文件,所以我想到了路径的问题,因为我们知道每个项目都...
  • 出现问题,我们一般会从问题日志的开始从头往后看,但是 在文档中会出现caused by 表示问题是由那个地方引起的因此,我们需要不断找到caused by ,找到最后一个caused by 就是问题的根本原因,这样就可以很快解决问题吃力...
  • 总结一下什么解决不了问题: 急躁,不耐烦;逃避(比如畏难情绪);抱怨,骂人;...经过分析找到问题的根本原因(重中之重),方法有:1)找到变量与不变量,对比更容易发现问题所在(key factor);
  • 在好奇心的驱使下,自己亲自写了一个,其他配置基本没问题,但就是一直报这个错,弄了我两天,终于在一篇文章中找到真正的解决方案(在检查B步骤中),如果确信基本的配置是没问题的,可直接看最后面的检查B步骤;...
  • Android 运行不正常关闭,在一堆报错里面找到了FAILED Binder Transaction。 百度了一下基本一致说法就是: 在Intent 中传递bitmap时,要限制图片小于40K. 看了一些解决方案,分为以下几种: 1.从根本出发直接...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,075
精华内容 430
关键字:

找到问题的根本原因