一、情况

抽象出问题是这样的:

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/

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

  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. 然后,在托管代码中就可以直接调用了。

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 错误的解决方法总结的更多相关文章

  1. 安装gem invalid date format in specification错误的解决方法

    别的不说,报错信息直接贴图: 解决方法: 1.找到你环境目录下的spec,例如:D:\Ruby187\lib\ruby\gems\1.8\specifications. 2.找到引起错误文件的gems ...

  2. Android Studio:xxx is not an enclosing class 错误的解决方法

    Android Studio:xxx is not an enclosing class 错误的解决方法 这个问题一般出现在内部类中,若要创建内部类的实例,需要有外部类的实例才行,或者是将内部类设置为 ...

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

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

  4. DataGrip:Error encountered when performing Introspect schema xxx 错误的解决方法

    datagrip的问题,转载自: https://www.cnblogs.com/geb515/p/7995249.html 把Introspect using JDBC _metadata打上勾 然 ...

  5. 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 ...

  6. VS2008 运行VC\Bin下的link.exe, cl.exe, lib.exe提示找不到mspdb80.dll的解决方法

    天在用link.EXE的LIB命令生成用于连接(LINK)使用的lib文件时提示:找不到mspdb80.dll. 原因:Microsoft Visual Studio\VC\Bin\下没有 “msob ...

  7. delphi “Invalid floating point operation.”错误的解决方法

    这两天用webbrower写东西,有时候打开SSL加密站点时会出现”Invalid floating point operation.”的错误,上网搜了下,把解决方法贴上. 导致原因 在Delphi2 ...

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

    这两天用webbrower写东西,有时候打开SSL加密网站时会出现”Invalid floating point operation.”的错误,上网搜了下,把解决方法贴上. 导致原因 在Delphi2 ...

  9. 微信jsSDK公众号开发时网页提示 invalid signature错误的解决方法

    微信公众号开发jsSDK,链接地址不能加?参数,可以通过#传递参数. 不然.页面wx.ready()时就会报错,用 wx.error(function (res) { alert("接口验证 ...

随机推荐

  1. web标准(复习)--7 横向导航菜单

    今天我们开始学习html列表,包含以下内容和知识点: 横向列表菜单 用图片美化的横向导航 css Sprites 一.横向列表菜单前边学习过纵向导航菜单,又学习了float属性,那么要实现横向导航菜单 ...

  2. math.h中的常量

    类似于Matlab中经常用到的一些常量,C++里边也是有的.(经查源文件无意中看到) 写入如下代码: #include<iostream> #include<iomanip> ...

  3. action找不到

    错误: {"name":"Not Found","message":"Unable to resolve the request: ...

  4. Python中unittest采用不同的参数组合产生独立的test case

    我们在使用Python的unittest做自动化或者单元测试时,有时需要一个测试用例根据不同的输入.输出组合而执行多次,但是,unittest中一个用例只能有一组参数组合执行,如果采用循环的方式,在生 ...

  5. Java学习笔记--“==”与"equals"

    java中的数据类型,可分为两类: 1. 基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boolean 他们之间的比较,应用双等号(==) ...

  6. poj2068--Nim

    题意:给你2n个人,两方各n个人,交叉坐,每个人可以取的石子有一个最大限制,总共有S颗石子,哪一方取了最后一颗石子就输了,问先取石子的这一方是否有必胜策略. DP,dp[i][j]代表第i个人还有J个 ...

  7. 使用QtScript库解析Json数组例子

    本文转载自:http://blog.sina.com.cn/s/blog_671732440100uwxh.html 使用qtscipt库解析json数组首先在工程文件中加 QT        += ...

  8. Decimal

    Description 任意一个分数都是有理数,对于任意一个有限小数,我们都可以表示成一个无限循环小数的形式(在其末尾添加0),对于任意一个无限循环小数都可以转化成一个分数.现在你的任务就是将任意一个 ...

  9. CSDN第四届在线编程大赛2014初赛:带通配符的数

    题目要求: 输入参数:参数A,含有任意个数的?的数值字符串,如:12?4,?代表一位任意数             参数B,不含?的数值字符串,长度与参数A一致输出结果:参数A比参数B大的可能数值个数 ...

  10. 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 ...