HEAP[xxx.exe]:Invalid Address specified to RtlValidateHeap 错误的解决方法总结

一、情况

抽象出问题是这样的:

class DLL_API1 A

{

func()

{

vector vec;

B b;

b.func(vec);

return TRUE;

}

}

其中B是另一个导出类,定义如下

class DLL_API2 B

{

private:

vector m_vec;

public:

func( vector &vec )

{

vec = m_vec;

}

}

运行时发现,每次运行到A的return TRUE释放vector的时候,都会报错:user breakpoint called from code at  xxxxxxxxxxxxx,并在Debug的提示框中出现:

HEAP[xxx.exe]:Invalid Address specified to RtlValidateHeap    的提示。

网上查了下,基本上都是说是dll和exe在不同的地方开辟了空间,在不同的地方释放的问题。看来以后还需要注意呢。

解决的方法是:

是外层被使用的内存,可以在外层定义后传参到非托管函数,在内部赋值后,在外层被调用,然后被释放;在内部被申请的空间,需在内部显式的的释放,避免造成内存泄露,这样就不会出现上述两种错误。(引用自:http://155134558.blog.163.com/blog/static/22278462009727103058451/

也就是说可以做如下修改:

[cpp] view plaincopy

  1. class DLL_API1 A
  2. {
  3. func()
  4. {
  5. B b;
  6. int nCnt = b.func1();
  7. vector vec;
  8. b.func2(vec);
  9. return TRUE;
  10. }
  11. }
  12. class DLL_API2 B
  13. {
  14. private:
  15. vector m_vec;
  16. public:
  17. int func1()
  18. {
  19. return m_vec.size();
  20. }
  21. func2( vector &vec )
  22. {
  23. vec = m_vec;
  24. }
  25. }

不过目前这种解决方案看起来是比较挫啦,不知道能不能从设计上避免。这个问题就先放在这里吧。以后有更多经验的时候再回头看。

二、情况

遇到该问题的原因是,托管代码和非托管代码之间的分配机制不同,两者之间可以进行互操作,下面是查到的相关内容:

经过一段时间对MSDN的钻研,终于明白C++/CLI互操作共分三种:

1.P/Invoke

2.Com interop

3.C++ interop

我想版主推荐的是指采用C++ interop方式。代码过程如下:

1.将非托管结构和函数放在#pragmaunmanaged内,像这样

#pragma unmanaged

struct cUserNestedStruct

{

.........

} ;

extern "C" int DllFunction(UserDefinedStruct**);

2. 然后,在托管代码中就可以直接调用了。

#pragma

managed

int main()

{

UserDefinedStruct*   mystruct = new UserDefinedStruct();

int num = DLLFunction(&mystruct);

}

上述是调用Dll,进行互操作的情况。

在我们的项目中,使用托管和非托管混合的方法,通过头文件,直接调用非托管程序。这里需要注意的是:托管代码的内存管理和非托管的内存管理是不同的。在内存堆的分配上也是不同的,所以,两者之间不能直接进行内存的互调用,例如:1,在非托管代码中不能释放托管代码申请的内存;

2,在非托管代码中申请的内存,在函数结束后就被释放,如果被return到托管环境里,是无效的地址。

是外层被使用的内存,可以在外层定义后传参到非托管函数,在内部赋值后,在外层被调用,然后被释放;在内部被申请的空间,需在内部显式的的释放,避免造成内存泄露,这样就不会出现上述两种错误。

本项目中的问题是在非托管代码中,使用了对托管代码中内存块的一个引用,然后在函数结束时,被释放,这样就是free掉了托管代码中申请的内存,会报错,访问无效的内存。

三、情况

在编译的时候,exe和dll有可能链接的是静态的运行时库,也有可能链接的是dll版本的运行时库。如果在exe或者是dll中有一个链接的是静态的运行时库,那么就会存在两套内存分配的实例。所以在dll中申请的内存,到exe中释放就会失败,因为exe并不认识那块内存。解决的办法就是都使用dll版本的运行时库,这样,在进程空间内,只有一个运行时实例。

四、情况

WCHAR aPathname[]=L"\\\\c:\\pbk_temp";

WCHAR aFilename[]=L"100.dat";

DWORD dwLimitedReadSize=0;

unsigned char* content;

content=NULL;

.......

dwResult = CONAReadFile(hFS, &FileInfo, content, dwLimitedReadSize, aPathname);

.........

delete [] content;

content=NULL;

CONAReadFile是Nokia提供的一个函数,原型为
DWORD CONAReadFile(FSHANDLE hFSHandle, LPCONAPI_FILE_INFO pFileInfo, unsigned char** ppFileData, DWORD dwLimitedReadSize, const WCHAR* pstrTargetPath)

现在我只要一执行delete [] content;程序就崩了。单步跟出现提示信息HEAP[PROPERTYSHEET.exe]: Invalid Address specified to RtlValidateHeap( 00A90000, 00197CC8 )

这是怎么回事?该怎么解决。如果不delete会不会造成内存泄漏。

原因:

在Nokia的库中同时提供了释放char* content的方法,因为char* content指向的内存是由dll中的方法分配的,所以应该由dll中的方法释放。这正好符合C++关于谁分配,谁释放的准侧。
从这个例子,我们可以看到,以后在写dll时,如果在dll中的某个方法内部分配了内存,同时要写一个释放该段内存的方法,对外公开,用来给外部的函数调用

五、情况

我封装了dll 原来是exe 现在封装成dll
发现了这个错误 函数都执行没问题 就是函数执行完 就爆这个错误
我没用dll什么的 就用了string

调用是

void CTestDlg::OnButton1()

{

// TODO: Add your control notification handler code here

UpdateData(TRUE);

string ts = m_text;

string sData = _ConvertHextoCString(ts);

AfxMessageBox(sData.c_str());

}

dll封装函数是

#include "stdafx.h"

#include <string>

using namespace std;

BOOL APIENTRY DllMain( HANDLE hModule,   DWORD  ul_reason_for_call, LPVOID lpReserved)

{

return TRUE;

}

string ConvertHextoString(string hex)

{

string result;

char temp[3];

int i = 0;

int nLen = hex.length();

if (nLen%2 != 0)

{

return "ERROR";

}

return result;

}

问题解决了 封装dll 最好类型不要用string 这样很容易有问题
还有就是在传入参数 加上const这样 就保证不会有问题了

六、情况

Dll之间由于由于空间分配和删除引起的

invalid address specified to rtlvalidateheap

在外层模块中定义了一个变量,传入内层模块赋值,用完后在外层模块释放时出错。

一个可能的原因:

在不同模块(工程)之间传递 C++ 类,而这两个模块用了不同的运行时库(Runtime Library)设置

例如:EXE 模块调用 DLL 模块里传递 C++ 类的函数,但 DLL 模块使用静态链接(Release 是 Multi-threaded (/MT)、Debug 是 Multi-threaded Debug (/MTd))方式编译,而 EXE 模块使用动态链接(Release 是 Multi-threaded DLL (/MD)、Debug 是 Multi-threaded Debug DLL (/MDd))方式编译。

可以对比这两个模块的工程属性 - C/C++ - Code Generation - Runtime Library,看看设置是否一样,如果不一样要改成一样的。

如果无法解决问题,那就是别的原因了。

七、情况

析构函数出问题

调试信息:

HEAP[MHPSO.exe]: Invalid Address specified to RtlValidateHeap( 00390000, 00DAAC68 )
Windows 已在 MHPSO.exe 中触发一个断点。

其原因可能是堆被损坏,这说明 MHPSO.exe 中或它所加载的任何 DLL 中有 Bug。

一般是野指针导致。

八、

转载自: http://www.bhcode.net/article/20100713/12048.html

//微粒类

class PARTICLE

{

public:

double *X;      //微粒的坐标数组

double *V;      //微粒的速度数组

double *XBest;  //微粒的最好位置数组

int Dim;        //微粒的维数

double Fit;     //微粒适合度

double FitBest; //微粒最好位置适合度

//构造函数

PARTICLE();     //空构造函数

PARTICLE(int n);//维数为参数的构造函数

//析构函数

~PARTICLE();

void SetDim(int d); //设置微粒的维数

};

//微粒构造函数

PARTICLE::PARTICLE() //空构造函数

{

X = 0; V = 0; XBest = 0; Dim = 0;

}

PARTICLE::PARTICLE(int n) //维数为参数的构造函数

{

if(n<0)

{

cout<<"输入有错,维数必须大于0"<<endl;

return;

}

Dim = n;

X = new double[Dim];

V = new double[Dim];

XBest = new double[Dim];

}

//微粒析构函数

PARTICLE::~PARTICLE()

{

if(Dim)

{

delete X;

delete V;

delete XBest;

X=0;

V=0;

XBest=0;

}

}

//定义群粒子类

class PSO

{

public:

PARTICLE * Particle;    //微粒群数组

int PNum;               //微粒个数

int GBestIndex;         //最好微粒索引

double W;               //惯性权重

double C1;              //加速度系数1

double C2;              //加速度系数2

double *Xup;            //微粒坐标上界数组

double *Xdown;          //微粒坐标下界数组

double *Vmax;           //微粒最大速度数组

void Initialize();      //初始化群体

void CalFit();          //计算全体适合度

virtual void ParticleFly(); //微粒飞翔,产生新一代微粒

//通讯函数,返回值为false时,系统停止优化

bool (*Com)(double,     //最优微粒适合度

double*,                //最优微粒坐标数组

double**,               //所有微粒坐标指针数组

int);                   //当前最优微粒索引

//构造函数

PSO(); //空构造函数

PSO(int dim, //微粒维数

int num); //微粒个数

//析构函数

~PSO();

};

//PSO构造函数

PSO::PSO()

{

Particle = 0;

PNum = 0;

GBestIndex = 0;

Xup = 0;

Xdown = 0;

W = 1;

C1 = 2;

C2 = 2;

Com = 0;

}

PSO::PSO(int dim, int num)

{

if(dim<0 || num <0)

{

cout<<"输入有错,维数和粒子个数必须大于0"<<endl;

return;

}

Particle = new PARTICLE[num];

for(int i=0; i< num; i++)

Particle[i].SetDim(dim);

PNum = num;

GBestIndex = 0;

Xup = new double[dim];

Xdown = new double[dim];

Vmax = new double[dim];

W = 1;

C1 = 2;

C2 = 2;

Com = 0;

}

//析构函数

PSO::~PSO()

{

if(Particle)

delete []Particle;

if(Xup)

delete []Xup;//位置上界

if(Xdown)

delete []Xdown;//位置下界

if(Vmax)

delete []Vmax; //速度上下界

Xup = 0;

Xdown = 0;

Vmax = 0;

Particle=0;

}

//派生多种群分层的PSO类

class MHPSO

{

public:

PSO** FirstPso; //第一层多种群粒子群的指针的指针

int L; //第一层种群的个数 = 第二层粒子群中粒子的个数

double C3; //加速度系数3

PSO* SecondPso;//第二层的粒子群指针

HANDLE wMutex;

double Vmin[20] ; //当粒子飞行速度小于Vmin的时,速度变化已不能更新粒子的位置,重新初始化速度

public:

MHPSO()

{

FirstPso=0; L=0; SecondPso=0; C3 = 2;

for(int i=0;i<20;i++)

Vmin[i] = 0.0001 ;

wMutex = ::CreateMutex(NULL,false,NULL);

}

//构造函数,给出微粒维数n 和种群个数L,种群中粒子的个数m

MHPSO(int n, int m,int L)

{

this->L = L;

FirstPso = new PSO*[L];

for(int i=0 ;i< L;i++)

FirstPso[i] = new PSO(n,m);

SecondPso = new PSO(n,L);

C3 = 2;

for(int i=0;i<20;i++)

Vmin[i] = 0.0001 ;

wMutex = ::CreateMutex(NULL,false,NULL);

}

~MHPSO()

{

for(int i=0;i<L;i++)

{

delete this->FirstPso[i];

this->FirstPso[i] =0;

}

delete []FirstPso;

this->FirstPso = 0;

delete SecondPso;

SecondPso =0; //这两句有问题。。。,如果去掉程序就不会出错。。

::CloseHandle(wMutex);

}

};

时间: 2024-08-01 18:25:15

HEAP[xxx.exe]:Invalid Address specified to RtlValidateHeap 错误的解决方法总结的相关文章

Django Ubuntu:Database returned an invalid value in QuerySet.dates(). 错误的解决方法

运行Windows下创建的Django项目时,发生此错误! Database returned an invalid value in QuerySet.dates(). Are time zone definitions and pytz installed? 按提示先安装pytz 1.先安装easy_install: sudo apt-get install python-setuptools 2.进入官网,获取下载地址,使用wget命令下载: wget https://pypi.pytho

SQLServer 报错:用户、组或角色&#39;XXX&#39; 在当前数据库中已存在. 错误:15023解决方法

背景: 最近在迁移SQLServer数据库2008时,新建用户后,做用户映射时. SQLServer 报错:用户.组或角色'XXX' 在当前数据库中已存在. 错误:15023. 下面讲一下解决的方法. 分析:    将数据库恢复到其他服务器时,数据库中包含一组用户和权限,但可能没有相应的登录或者登录所关联的用户可能不是相同的用户.    这种情况被称为存在"孤立用户".此时是不能通过新建登录或者是对同名登录授予对应数据库的"用户"权限来解决登录问题,    因为SQ

Type cvc-complex-type.2.4.a: Invalid content was found starting with element &#39;build&#39;.错误的解决方法

项目突然间爆出了这样的问题: Description Resource Path Location Typecvc-complex-type.2.4.a: Invalid content was found starting with element 'build'. One of '{"http://maven.apache.org/POM/4.0.0":parent, "http://maven.apache.org/POM/4.0.0":name, "

关于delphi软件运行出现Invalid floating point operation的错误的解决办法

关于delphi软件运行出现Invalid floating point operation的错误的解决办法 关于delphi软件运行出现Invalid floating point operation的错误的解决办法软件如果有webbrowser载入网页的时候经常会出现这个错误.这个错误是webbrowser3个Bug之一.具体行程的原因大概我也不知道.基本是如果XP系统编译的,放到vista或者V7就容易出现这个错误.具体解决的办法也是很简单的.查看官方的解决办法如下.When runnin

Source insight 3572版本安装及An invalid source insight serial number was detected解决方法

Source insight有最新版3572.3.50.0076 下载连接:http://www.sourceinsight.com/down35.html,   http://www.sourceinsight.com/distribute/Si3570Setup.exe 注册号:SI3US-205035-36448 1.卸载掉旧版安装新版, 可能会有提示" An invalid source insight serial number was detected",然后不能使用. 解

maven执行打包命令(mvn package)是出现Java heap space错误的解决方法(windows环境)

今天执行maven的打包命令出现时内存溢出的错误,以下为解决方法 找到mvn目录下bin目录里的mvn.bat, 找到@REM set MAVEN_OPTS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000, 在这局下添加以下语句: set MAVEN_OPTS=-Xms256m -Xmx768m -XX:PermSize=128m -XX:Ma

Delphi “Invalid floating point operation.”错误的解决方法(使用System单元提供的Set8087CW函数禁用浮点异常)

这两天用webbrower写东西,有时候打开SSL加密网站时会出现”Invalid floating point operation.”的错误,上网搜了下,把解决方法贴上. 导致原因 在Delphi2011中需要通过浮点单位控制指令设置浮点运算单位.浮点单位控制指令控制着浮点运算的精度.四舍五入的方式以及特定的浮点运算是否触发异常.可以参阅Intel处理器的详细文档. 在Delphi2011中有函数可以直接访问处理器的控制指令.比如,可以使用Set8087CW函数改变8087CW控制指令的值,从

VS2012(2013、2015) OpenCV “HEAP:Invalid Address specified to RtlValidateHeap( 000D0000, 019FEF18 )

近期拿起一个openCV程序跑了一下,是VS2013 + OpenCV2.4.8,运行的时候如下错误: 百度,谷歌了很久,给出的办法都无法解决,于是又装了VS2012 VS2015一样的错误,但是别人又可以正常运行.在绝望之时,发现这个哥们的博文http://blog.csdn.net/sacomplex/article/details/44402149 居然解决了,实在不知为什么 解决方法 在 项目 -> 属性 -> 配置属性 -> 常规 -> 平台工具集 把 Visual St

VS2017创建控制台应用后,编写完代码调试正常,使用exe文件直接执行出现闪退情况解决方法。

这是因为代码中包含的相对路径的原因. 解决办法:把项目中包含的所有相对路径修改为绝对路径. (个人觉得因为直接执行exe文件,默认打开在C盘的用户目录下.) 例如: std::string DATA_DIR = "data/"; 修改为: std::string DATA_DIR = "E:/VS2017_Project/Project1/Identification/data/"; 我尝试把路径加入到系统环境变量中,也没有成功. 在CMD命令行中,切换目录到VS2