HEAP[xxx.exe]:Invalid Address specified to RtlValidateHeap 错误的解决方法总结
一、情况
抽象出问题是这样的:
class DLL_API1 A
{
func()
{
vector vec;
B b;
b.func(vec);
return TRUE;
}
}
其中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/)
也就是说可以做如下修改:
- class DLL_API1 A
- {
- func()
- {
- B b;
- int nCnt = b.func1();
- vector vec;
- b.func2(vec);
- return TRUE;
- }
- }
- class DLL_API2 B
- {
- private:
- vector m_vec;
- public:
- int func1()
- {
- return m_vec.size();
- }
- func2( vector &vec )
- {
- vec = m_vec;
- }
- }
不过目前这种解决方案看起来是比较挫啦,不知道能不能从设计上避免。这个问题就先放在这里吧。以后有更多经验的时候再回头看。
二、情况
遇到该问题的原因是,托管代码和非托管代码之间的分配机制不同,两者之间可以进行互操作,下面是查到的相关内容:
经过一段时间对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. 然后,在托管代码中就可以直接调用了。
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);
}
};
HEAP[xxx.exe]:Invalid Address specified to RtlValidateHeap 错误的解决方法总结的更多相关文章
- 安装gem invalid date format in specification错误的解决方法
别的不说,报错信息直接贴图: 解决方法: 1.找到你环境目录下的spec,例如:D:\Ruby187\lib\ruby\gems\1.8\specifications. 2.找到引起错误文件的gems ...
- Android Studio:xxx is not an enclosing class 错误的解决方法
Android Studio:xxx is not an enclosing class 错误的解决方法 这个问题一般出现在内部类中,若要创建内部类的实例,需要有外部类的实例才行,或者是将内部类设置为 ...
- 关于delphi软件运行出现Invalid floating point operation的错误的解决办法
关于delphi软件运行出现Invalid floating point operation的错误的解决办法 关于delphi软件运行出现Invalid floating point operat ...
- DataGrip:Error encountered when performing Introspect schema xxx 错误的解决方法
datagrip的问题,转载自: https://www.cnblogs.com/geb515/p/7995249.html 把Introspect using JDBC _metadata打上勾 然 ...
- 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.sourcei ...
- VS2008 运行VC\Bin下的link.exe, cl.exe, lib.exe提示找不到mspdb80.dll的解决方法
天在用link.EXE的LIB命令生成用于连接(LINK)使用的lib文件时提示:找不到mspdb80.dll. 原因:Microsoft Visual Studio\VC\Bin\下没有 “msob ...
- delphi “Invalid floating point operation.”错误的解决方法
这两天用webbrower写东西,有时候打开SSL加密站点时会出现”Invalid floating point operation.”的错误,上网搜了下,把解决方法贴上. 导致原因 在Delphi2 ...
- Delphi “Invalid floating point operation.”错误的解决方法(使用System单元提供的Set8087CW函数禁用浮点异常)
这两天用webbrower写东西,有时候打开SSL加密网站时会出现”Invalid floating point operation.”的错误,上网搜了下,把解决方法贴上. 导致原因 在Delphi2 ...
- 微信jsSDK公众号开发时网页提示 invalid signature错误的解决方法
微信公众号开发jsSDK,链接地址不能加?参数,可以通过#传递参数. 不然.页面wx.ready()时就会报错,用 wx.error(function (res) { alert("接口验证 ...
随机推荐
- web标准(复习)--7 横向导航菜单
今天我们开始学习html列表,包含以下内容和知识点: 横向列表菜单 用图片美化的横向导航 css Sprites 一.横向列表菜单前边学习过纵向导航菜单,又学习了float属性,那么要实现横向导航菜单 ...
- math.h中的常量
类似于Matlab中经常用到的一些常量,C++里边也是有的.(经查源文件无意中看到) 写入如下代码: #include<iostream> #include<iomanip> ...
- action找不到
错误: {"name":"Not Found","message":"Unable to resolve the request: ...
- Python中unittest采用不同的参数组合产生独立的test case
我们在使用Python的unittest做自动化或者单元测试时,有时需要一个测试用例根据不同的输入.输出组合而执行多次,但是,unittest中一个用例只能有一组参数组合执行,如果采用循环的方式,在生 ...
- Java学习笔记--“==”与"equals"
java中的数据类型,可分为两类: 1. 基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boolean 他们之间的比较,应用双等号(==) ...
- poj2068--Nim
题意:给你2n个人,两方各n个人,交叉坐,每个人可以取的石子有一个最大限制,总共有S颗石子,哪一方取了最后一颗石子就输了,问先取石子的这一方是否有必胜策略. DP,dp[i][j]代表第i个人还有J个 ...
- 使用QtScript库解析Json数组例子
本文转载自:http://blog.sina.com.cn/s/blog_671732440100uwxh.html 使用qtscipt库解析json数组首先在工程文件中加 QT += ...
- Decimal
Description 任意一个分数都是有理数,对于任意一个有限小数,我们都可以表示成一个无限循环小数的形式(在其末尾添加0),对于任意一个无限循环小数都可以转化成一个分数.现在你的任务就是将任意一个 ...
- CSDN第四届在线编程大赛2014初赛:带通配符的数
题目要求: 输入参数:参数A,含有任意个数的?的数值字符串,如:12?4,?代表一位任意数 参数B,不含?的数值字符串,长度与参数A一致输出结果:参数A比参数B大的可能数值个数 ...
- URAL 2038 Minimum Vertex Cover
2038. Minimum Vertex Cover Time limit: 1.0 secondMemory limit: 64 MB A vertex cover of a graph is a ...