主程序中有关代码:
//之前代码给三个二维数组分配内存,并取得前两个数组的数据
//前两个数组的数据输出到TMemo组件中检查无误
//下面这个DLL中的函数将前两个二维数组运算后存入第三个二维数组
typedef void (*MyCalcFunc)(double** ,int ,double**,int ,int ,double ,double**);
typedef int (*MyInfoFunc)(HWND, HWND, LPVOID);
HINSTANCE hiDllFile;
MyCalcFunc RelationFunc;
MyInfoFunc ShowDllInfo;
hiDllFile=LoadLibrary("Relation.dll");
RelationFunc=(MyCalcFunc)GetProcAddress(hiDllFile,"RelationGrade");
ShowDllInfo=(MyInfoFunc)GetProcAddress(hiDllFile,"ShowMethodInfo");
ShowDllInfo(this->Handle,NULL,NULL);
RelationFunc(X,XRow,Y,YRow,Col,0.5,R);
float test=0.0;
for(int i=0;i<YRow;++i)
{
// AnsiString as=""; //加上就出错
for(int j=0;j<XRow;++j)
{
test+= R[i][j];//FormatFloat("##0.000",R[i][j]) + " ";
}
//mmo1->Lines->Add("Total:"); //加上就出错
//mmo1->Lines->Add(FloatToStr(test));//加上就出错
//mmo1->Lines->Add(as); //加上就出错
}
ShowMessage(FloatToStr(test));//这句没错,结果也正确
FreeLibrary(hiDllFile);
18 个解决方案
#1
别沾AnsiString
用char*
用char*
#2
重复定义 as ????????
#3
没有遇到过,应该你的代码和逻辑有问题。
#4
发现了,只要不使用AnsiString就没有问题,比如单步跟踪,R[0][0]本来是0.821,在那个循环后加一条语句AnsiString aaa="";则这个语句过后,R[0][0],变成了4.641!
看来如daydayup234(关中刀客) 所说,不能用AnsiString!?可是我要将结果显示出来,那怎么整!?要显示,总会用到AnsiString的吧!?
看来如daydayup234(关中刀客) 所说,不能用AnsiString!?可是我要将结果显示出来,那怎么整!?要显示,总会用到AnsiString的吧!?
#5
你的内存溢出啦。
#6
还没怎么仔细看,看看先……
#7
dll里用 char * 代替AnsiString
#8
很明显是内存溢出了!字符串的处理最怕这种
#9
为什么会溢出?是因为DLL里面的代码,还是因为别的原因?为什么不使用AnsiString就不会溢出?
BTW:什么叫溢出?汗。。。。。。。
BTW:什么叫溢出?汗。。。。。。。
#10
AnsiString是一个VCL的类,而在dll中最好用char *,这样才能通用,不然只能bcb和delphi用了
#11
AnsiString as="";
这样也出错,内存肯定是乱套了.(因内存乱套,导致调试器找不到期正确的出错行.),这现象是dll中使用了不该使用的内存,估计是:
1, Dll中有溢出代码. 2,调用约定不对. 第2点可能较大.
typedef void (*MyCalcFunc)(double** ,int ,double**,int ,int ,double ,double**);
typedef int (*MyInfoFunc)(HWND, HWND, LPVOID);
这两个是DLL中的函数吧,没使用AnsiString啊. 可能是调用约定不对,你找一下那dll里的定义看看调用约定是不是这样的.
这样也出错,内存肯定是乱套了.(因内存乱套,导致调试器找不到期正确的出错行.),这现象是dll中使用了不该使用的内存,估计是:
1, Dll中有溢出代码. 2,调用约定不对. 第2点可能较大.
typedef void (*MyCalcFunc)(double** ,int ,double**,int ,int ,double ,double**);
typedef int (*MyInfoFunc)(HWND, HWND, LPVOID);
这两个是DLL中的函数吧,没使用AnsiString啊. 可能是调用约定不对,你找一下那dll里的定义看看调用约定是不是这样的.
#12
如果是使用vector 这样的数组,在调试模式下,DLL中就比较容易找出错误所在, 使用C类型的数组出错是比较难查的.
#13
本想上午贴出代码,结果突然不能上CSDN,无奈,现在来贴出DLL中的代码:
//-----------------------------H----------------------------------
extern "C" __declspec(dllexport)
int __stdcall RelationGrade(double** X,int XRow,double **Y,int YRow,int Col,double E,double** R);
double Min(double** X,int XRow,double **Y,int Col,int YIndex);
double Max(double** X,int XRow,double **Y,int Col,int YIndex);
//----------------------------CPP----------------------------------
#include "RelationshipUnit.h"
#include <math.h>
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport)
int __stdcall RelationGrade(double** X,int XRow,double **Y,int YRow,int Col,double E,double** R)
{//输入参数:
// X: 子因素(二维数组)
// Y: 母因素(二维数组)
// XRow: 子因素个数
// YRow: 母因素个数
// Col: 每因素属性个数
// E: 分辨系数
//输出参数:
// R: 母因素对子因素的关联度(YRow * XRow矩阵)
//说明:
// XRow,YRow,Col限定了X,Y的大小
//返回值
// 0: 成功执行
// > 0:
// -1: 子元素首列含零值
// -2: 母元素首列含零值
// -3: 内存不足
// -4: 数据格式不对,计算过程出现分母为零
//判断子母因素数组是否符合要求——首列数据不能有零值,否则无法归一化
for(int i=0;i<XRow;++i)
{
if(X[i][0]<=0.0000001 && X[i][0] >=-0.0000001)
{
return -1;
}
}
for(int i=0;i<YRow;++i)
{
if(Y[i][0]<=0.0000001 && Y[i][0] >=-0.0000001)
{
return -2;
}
}
double **X_Unitary;//归一子因素
double **Y_Unitary;//归一母因素
try
{//数组分配一维空间
X_Unitary=new double* [XRow];
Y_Unitary=new double* [YRow];
}
catch(...)
{//内存不足
if(X_Unitary!=NULL)
{
delete X_Unitary;
X_Unitary=NULL;
}
return -3;
}
for(int i=0;i<XRow;++i)
{//子因素归一化数组分配空间
try
{
X_Unitary[i]=new double[Col];
}
catch(...)
{
for(int j=0;j<i;++j)
{
delete X_Unitary[j];
X_Unitary[j]=NULL;
}
delete X_Unitary;
X_Unitary=NULL;
delete Y_Unitary;
Y_Unitary=NULL;
return -3;
}
}
for(int i=0;i<YRow;++i)
{///母因素归一化数组分配空间
try
{
Y_Unitary[i]=new double[Col];
}
catch(...)
{
for(int j=0;j<i;++j)
{
delete Y_Unitary[j];
Y_Unitary[j]=NULL;
}
for(int j=0;j<XRow;++j)
{
delete X_Unitary[j];
X_Unitary[j]=NULL;
}
delete X_Unitary;
X_Unitary=NULL;
delete Y_Unitary;
Y_Unitary=NULL;
return -3;
}
}
//--
//归一化
for(int i=0;i<XRow;++i)
{
for(int j=0;j<Col;++j)
{
X_Unitary[i][j]=X[i][j]/X[i][0];
}
}
for(int i=0;i<YRow;++i)
{
for(int j=0;j<Col;++j)
{
Y_Unitary[i][j]=Y[i][j]/Y[i][0];
}
}
//以下省略内存分配失败判断,因为基本上不可能失败
double* fMin=new double [YRow];
double* fMax=new double [YRow];
for(int i=0;i<YRow;++i)
{
fMin[i]=Min(X_Unitary,XRow,Y_Unitary,Col,i);
fMax[i]=Max(X_Unitary,XRow,Y_Unitary,Col,i);
}
for(int j=0;j<YRow;++j)
{//计算结果
for(int i=0;i<XRow;++i)
{
R[j][i]=0.0;
for(int k=0;k<Col;++k)
{
double sub=fabs(Y_Unitary[j][k]-X_Unitary[i][k]);
double kefai;
if((sub + E*fMax[j])<=0.000001 && (sub + E*fMax[j]) >=-0.000001)
{//数据格式不符合,分母为零。
//回收内存
for(int i=0;i<XRow;++i)
{
delete X_Unitary[i];
}
delete X_Unitary;
for(int i=0;i<YRow;++i)
{
delete Y_Unitary[i];
}
delete Y_Unitary;
delete fMin;
delete fMax;
return -4;
}
kefai=(fMin[j] + E*fMax[j]) / (sub + E*fMax[j]);
R[j][i]+=kefai;
}
R[j][i]/=Col;
}
}
//回收内存
for(int i=0;i<XRow;++i)
{
delete X_Unitary[i];
}
delete X_Unitary;
for(int i=0;i<YRow;++i)
{
delete Y_Unitary[i];
}
delete Y_Unitary;
delete fMin;
delete fMax;
//--
return 0;
}
//---------------------------------------------------------------------------
double Min(double** X,int XRow,double **Y,int Col,int YIndex)
{
double result=0.0;
for(int i=0;i<XRow;++i)
{
double mink=0.0;
for(int k=0;k<Col;++k)
{
double tmp=fabs(Y[YIndex][k]-X[i][k]);
if(k==0)
{
mink = tmp;
}
else if(mink > tmp)
{
mink=tmp;
}
}
if(i==0)
{
result = mink;
}
else if(result > mink)
{
result = mink;
}
}
return result;
}
//---------------------------------------------------------------------------
double Max(double** X,int XRow,double **Y,int Col,int YIndex)
{
double result=0.0;
for(int i=0;i<XRow;++i)
{
double mink=0.0;
for(int k=0;k<Col;++k)
{
double tmp=fabs(Y[YIndex][k]-X[i][k]);
if(k==0)
{
mink = tmp;
}
else if(mink < tmp)
{
mink = tmp;
}
}
if(i==0)
{
result = mink;
}
else if(result < mink)
{
result = mink;
}
}
return result;
}
//---------------------------------------------------------------------------
//-----------------------------H----------------------------------
extern "C" __declspec(dllexport)
int __stdcall RelationGrade(double** X,int XRow,double **Y,int YRow,int Col,double E,double** R);
double Min(double** X,int XRow,double **Y,int Col,int YIndex);
double Max(double** X,int XRow,double **Y,int Col,int YIndex);
//----------------------------CPP----------------------------------
#include "RelationshipUnit.h"
#include <math.h>
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport)
int __stdcall RelationGrade(double** X,int XRow,double **Y,int YRow,int Col,double E,double** R)
{//输入参数:
// X: 子因素(二维数组)
// Y: 母因素(二维数组)
// XRow: 子因素个数
// YRow: 母因素个数
// Col: 每因素属性个数
// E: 分辨系数
//输出参数:
// R: 母因素对子因素的关联度(YRow * XRow矩阵)
//说明:
// XRow,YRow,Col限定了X,Y的大小
//返回值
// 0: 成功执行
// > 0:
// -1: 子元素首列含零值
// -2: 母元素首列含零值
// -3: 内存不足
// -4: 数据格式不对,计算过程出现分母为零
//判断子母因素数组是否符合要求——首列数据不能有零值,否则无法归一化
for(int i=0;i<XRow;++i)
{
if(X[i][0]<=0.0000001 && X[i][0] >=-0.0000001)
{
return -1;
}
}
for(int i=0;i<YRow;++i)
{
if(Y[i][0]<=0.0000001 && Y[i][0] >=-0.0000001)
{
return -2;
}
}
double **X_Unitary;//归一子因素
double **Y_Unitary;//归一母因素
try
{//数组分配一维空间
X_Unitary=new double* [XRow];
Y_Unitary=new double* [YRow];
}
catch(...)
{//内存不足
if(X_Unitary!=NULL)
{
delete X_Unitary;
X_Unitary=NULL;
}
return -3;
}
for(int i=0;i<XRow;++i)
{//子因素归一化数组分配空间
try
{
X_Unitary[i]=new double[Col];
}
catch(...)
{
for(int j=0;j<i;++j)
{
delete X_Unitary[j];
X_Unitary[j]=NULL;
}
delete X_Unitary;
X_Unitary=NULL;
delete Y_Unitary;
Y_Unitary=NULL;
return -3;
}
}
for(int i=0;i<YRow;++i)
{///母因素归一化数组分配空间
try
{
Y_Unitary[i]=new double[Col];
}
catch(...)
{
for(int j=0;j<i;++j)
{
delete Y_Unitary[j];
Y_Unitary[j]=NULL;
}
for(int j=0;j<XRow;++j)
{
delete X_Unitary[j];
X_Unitary[j]=NULL;
}
delete X_Unitary;
X_Unitary=NULL;
delete Y_Unitary;
Y_Unitary=NULL;
return -3;
}
}
//--
//归一化
for(int i=0;i<XRow;++i)
{
for(int j=0;j<Col;++j)
{
X_Unitary[i][j]=X[i][j]/X[i][0];
}
}
for(int i=0;i<YRow;++i)
{
for(int j=0;j<Col;++j)
{
Y_Unitary[i][j]=Y[i][j]/Y[i][0];
}
}
//以下省略内存分配失败判断,因为基本上不可能失败
double* fMin=new double [YRow];
double* fMax=new double [YRow];
for(int i=0;i<YRow;++i)
{
fMin[i]=Min(X_Unitary,XRow,Y_Unitary,Col,i);
fMax[i]=Max(X_Unitary,XRow,Y_Unitary,Col,i);
}
for(int j=0;j<YRow;++j)
{//计算结果
for(int i=0;i<XRow;++i)
{
R[j][i]=0.0;
for(int k=0;k<Col;++k)
{
double sub=fabs(Y_Unitary[j][k]-X_Unitary[i][k]);
double kefai;
if((sub + E*fMax[j])<=0.000001 && (sub + E*fMax[j]) >=-0.000001)
{//数据格式不符合,分母为零。
//回收内存
for(int i=0;i<XRow;++i)
{
delete X_Unitary[i];
}
delete X_Unitary;
for(int i=0;i<YRow;++i)
{
delete Y_Unitary[i];
}
delete Y_Unitary;
delete fMin;
delete fMax;
return -4;
}
kefai=(fMin[j] + E*fMax[j]) / (sub + E*fMax[j]);
R[j][i]+=kefai;
}
R[j][i]/=Col;
}
}
//回收内存
for(int i=0;i<XRow;++i)
{
delete X_Unitary[i];
}
delete X_Unitary;
for(int i=0;i<YRow;++i)
{
delete Y_Unitary[i];
}
delete Y_Unitary;
delete fMin;
delete fMax;
//--
return 0;
}
//---------------------------------------------------------------------------
double Min(double** X,int XRow,double **Y,int Col,int YIndex)
{
double result=0.0;
for(int i=0;i<XRow;++i)
{
double mink=0.0;
for(int k=0;k<Col;++k)
{
double tmp=fabs(Y[YIndex][k]-X[i][k]);
if(k==0)
{
mink = tmp;
}
else if(mink > tmp)
{
mink=tmp;
}
}
if(i==0)
{
result = mink;
}
else if(result > mink)
{
result = mink;
}
}
return result;
}
//---------------------------------------------------------------------------
double Max(double** X,int XRow,double **Y,int Col,int YIndex)
{
double result=0.0;
for(int i=0;i<XRow;++i)
{
double mink=0.0;
for(int k=0;k<Col;++k)
{
double tmp=fabs(Y[YIndex][k]-X[i][k]);
if(k==0)
{
mink = tmp;
}
else if(mink < tmp)
{
mink = tmp;
}
}
if(i==0)
{
result = mink;
}
else if(result < mink)
{
result = mink;
}
}
return result;
}
//---------------------------------------------------------------------------
#14
我自己感觉没有什么不对的地方,汗。
还有,像我这种一个函数内需要new多个数组的情况,如何能保证内存被正确的回收?假设要用到有四个数组A、B、C、D,那么:
情况1:A已经new出来了,后来new B的时候出现了错误,就要delete A然后返回
情况2:A、B已经new出来了,后来new C的时候出现了错误,就要delete A、B然后返回
情况3:A、B、C已经new出来了,后来new D的时候出现了错误,就要delete A、B、C然后返回
情况4:A、B、C都new好了,但是经过一些计算发现继续运行的条件不符合,所以就要delete A、B、C然后返回;
情况5:函数顺利运行完毕,就要delete A、B、C、D然后返回
情况N:。。。。。。。。。。。
可能有N中情况,数组可能也不止四个,如何能通过一个简便的方法来控制内存的回收?每次都是try然后在catch里面delete已经分配好的数组太繁琐了,如果是二维数组就更繁琐了。
还有,像我这种一个函数内需要new多个数组的情况,如何能保证内存被正确的回收?假设要用到有四个数组A、B、C、D,那么:
情况1:A已经new出来了,后来new B的时候出现了错误,就要delete A然后返回
情况2:A、B已经new出来了,后来new C的时候出现了错误,就要delete A、B然后返回
情况3:A、B、C已经new出来了,后来new D的时候出现了错误,就要delete A、B、C然后返回
情况4:A、B、C都new好了,但是经过一些计算发现继续运行的条件不符合,所以就要delete A、B、C然后返回;
情况5:函数顺利运行完毕,就要delete A、B、C、D然后返回
情况N:。。。。。。。。。。。
可能有N中情况,数组可能也不止四个,如何能通过一个简便的方法来控制内存的回收?每次都是try然后在catch里面delete已经分配好的数组太繁琐了,如果是二维数组就更繁琐了。
#15
導出與調用時都加上__stdcall吧,記得BCB中默認好象不是__stdcall.
習慣上寫DLL時都指定調用約定,而不用默認約定。
typedef void (__stdcall *MyCalcFunc)(double** ,int ,double**,int ,int ,double ,double**);
typedef int (__stdcall *MyInfoFunc)(HWND, HWND, LPVOID);
習慣上寫DLL時都指定調用約定,而不用默認約定。
typedef void (__stdcall *MyCalcFunc)(double** ,int ,double**,int ,int ,double ,double**);
typedef int (__stdcall *MyInfoFunc)(HWND, HWND, LPVOID);
#16
用std::vector做多維數組,沒那麼多內存問題。做一維數組更沒問題。
要控制內存的釋放時刻可考慮用 std::auto_ptr
你是寫dll , 可考慮Dll內部用vector實現,對外接口用C指針,這樣別的編譯器也能使用。
要控制內存的釋放時刻可考慮用 std::auto_ptr
你是寫dll , 可考慮Dll內部用vector實現,對外接口用C指針,這樣別的編譯器也能使用。
#17
看来是约定的问题,加上__stdcall 之后就没问题了,我看了,Builder默认是__fastcall。多谢以上各位朋友啦,特别感谢PPower(月亮光光,照地堂)。
vector我接触过,不过我不想在DLL里用,按你的说法,看样vector是没问题的,有机会我会改成vector实现的。
关于auto_ptr,我没接触过,我会去看看的!
结贴了。
vector我接触过,不过我不想在DLL里用,按你的说法,看样vector是没问题的,有机会我会改成vector实现的。
关于auto_ptr,我没接触过,我会去看看的!
结贴了。
#18
哦,Mark一下,哈哈。我写的这个DLL是个关联度分析算法,属于灰度理论,留下这些关键字以便于以后有人能搜索到:)。希望搜索到的人用到了可以通知我一下(uhian#hotmail.com),让我有点成就感,咳咳。。。。。。
#1
别沾AnsiString
用char*
用char*
#2
重复定义 as ????????
#3
没有遇到过,应该你的代码和逻辑有问题。
#4
发现了,只要不使用AnsiString就没有问题,比如单步跟踪,R[0][0]本来是0.821,在那个循环后加一条语句AnsiString aaa="";则这个语句过后,R[0][0],变成了4.641!
看来如daydayup234(关中刀客) 所说,不能用AnsiString!?可是我要将结果显示出来,那怎么整!?要显示,总会用到AnsiString的吧!?
看来如daydayup234(关中刀客) 所说,不能用AnsiString!?可是我要将结果显示出来,那怎么整!?要显示,总会用到AnsiString的吧!?
#5
你的内存溢出啦。
#6
还没怎么仔细看,看看先……
#7
dll里用 char * 代替AnsiString
#8
很明显是内存溢出了!字符串的处理最怕这种
#9
为什么会溢出?是因为DLL里面的代码,还是因为别的原因?为什么不使用AnsiString就不会溢出?
BTW:什么叫溢出?汗。。。。。。。
BTW:什么叫溢出?汗。。。。。。。
#10
AnsiString是一个VCL的类,而在dll中最好用char *,这样才能通用,不然只能bcb和delphi用了
#11
AnsiString as="";
这样也出错,内存肯定是乱套了.(因内存乱套,导致调试器找不到期正确的出错行.),这现象是dll中使用了不该使用的内存,估计是:
1, Dll中有溢出代码. 2,调用约定不对. 第2点可能较大.
typedef void (*MyCalcFunc)(double** ,int ,double**,int ,int ,double ,double**);
typedef int (*MyInfoFunc)(HWND, HWND, LPVOID);
这两个是DLL中的函数吧,没使用AnsiString啊. 可能是调用约定不对,你找一下那dll里的定义看看调用约定是不是这样的.
这样也出错,内存肯定是乱套了.(因内存乱套,导致调试器找不到期正确的出错行.),这现象是dll中使用了不该使用的内存,估计是:
1, Dll中有溢出代码. 2,调用约定不对. 第2点可能较大.
typedef void (*MyCalcFunc)(double** ,int ,double**,int ,int ,double ,double**);
typedef int (*MyInfoFunc)(HWND, HWND, LPVOID);
这两个是DLL中的函数吧,没使用AnsiString啊. 可能是调用约定不对,你找一下那dll里的定义看看调用约定是不是这样的.
#12
如果是使用vector 这样的数组,在调试模式下,DLL中就比较容易找出错误所在, 使用C类型的数组出错是比较难查的.
#13
本想上午贴出代码,结果突然不能上CSDN,无奈,现在来贴出DLL中的代码:
//-----------------------------H----------------------------------
extern "C" __declspec(dllexport)
int __stdcall RelationGrade(double** X,int XRow,double **Y,int YRow,int Col,double E,double** R);
double Min(double** X,int XRow,double **Y,int Col,int YIndex);
double Max(double** X,int XRow,double **Y,int Col,int YIndex);
//----------------------------CPP----------------------------------
#include "RelationshipUnit.h"
#include <math.h>
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport)
int __stdcall RelationGrade(double** X,int XRow,double **Y,int YRow,int Col,double E,double** R)
{//输入参数:
// X: 子因素(二维数组)
// Y: 母因素(二维数组)
// XRow: 子因素个数
// YRow: 母因素个数
// Col: 每因素属性个数
// E: 分辨系数
//输出参数:
// R: 母因素对子因素的关联度(YRow * XRow矩阵)
//说明:
// XRow,YRow,Col限定了X,Y的大小
//返回值
// 0: 成功执行
// > 0:
// -1: 子元素首列含零值
// -2: 母元素首列含零值
// -3: 内存不足
// -4: 数据格式不对,计算过程出现分母为零
//判断子母因素数组是否符合要求——首列数据不能有零值,否则无法归一化
for(int i=0;i<XRow;++i)
{
if(X[i][0]<=0.0000001 && X[i][0] >=-0.0000001)
{
return -1;
}
}
for(int i=0;i<YRow;++i)
{
if(Y[i][0]<=0.0000001 && Y[i][0] >=-0.0000001)
{
return -2;
}
}
double **X_Unitary;//归一子因素
double **Y_Unitary;//归一母因素
try
{//数组分配一维空间
X_Unitary=new double* [XRow];
Y_Unitary=new double* [YRow];
}
catch(...)
{//内存不足
if(X_Unitary!=NULL)
{
delete X_Unitary;
X_Unitary=NULL;
}
return -3;
}
for(int i=0;i<XRow;++i)
{//子因素归一化数组分配空间
try
{
X_Unitary[i]=new double[Col];
}
catch(...)
{
for(int j=0;j<i;++j)
{
delete X_Unitary[j];
X_Unitary[j]=NULL;
}
delete X_Unitary;
X_Unitary=NULL;
delete Y_Unitary;
Y_Unitary=NULL;
return -3;
}
}
for(int i=0;i<YRow;++i)
{///母因素归一化数组分配空间
try
{
Y_Unitary[i]=new double[Col];
}
catch(...)
{
for(int j=0;j<i;++j)
{
delete Y_Unitary[j];
Y_Unitary[j]=NULL;
}
for(int j=0;j<XRow;++j)
{
delete X_Unitary[j];
X_Unitary[j]=NULL;
}
delete X_Unitary;
X_Unitary=NULL;
delete Y_Unitary;
Y_Unitary=NULL;
return -3;
}
}
//--
//归一化
for(int i=0;i<XRow;++i)
{
for(int j=0;j<Col;++j)
{
X_Unitary[i][j]=X[i][j]/X[i][0];
}
}
for(int i=0;i<YRow;++i)
{
for(int j=0;j<Col;++j)
{
Y_Unitary[i][j]=Y[i][j]/Y[i][0];
}
}
//以下省略内存分配失败判断,因为基本上不可能失败
double* fMin=new double [YRow];
double* fMax=new double [YRow];
for(int i=0;i<YRow;++i)
{
fMin[i]=Min(X_Unitary,XRow,Y_Unitary,Col,i);
fMax[i]=Max(X_Unitary,XRow,Y_Unitary,Col,i);
}
for(int j=0;j<YRow;++j)
{//计算结果
for(int i=0;i<XRow;++i)
{
R[j][i]=0.0;
for(int k=0;k<Col;++k)
{
double sub=fabs(Y_Unitary[j][k]-X_Unitary[i][k]);
double kefai;
if((sub + E*fMax[j])<=0.000001 && (sub + E*fMax[j]) >=-0.000001)
{//数据格式不符合,分母为零。
//回收内存
for(int i=0;i<XRow;++i)
{
delete X_Unitary[i];
}
delete X_Unitary;
for(int i=0;i<YRow;++i)
{
delete Y_Unitary[i];
}
delete Y_Unitary;
delete fMin;
delete fMax;
return -4;
}
kefai=(fMin[j] + E*fMax[j]) / (sub + E*fMax[j]);
R[j][i]+=kefai;
}
R[j][i]/=Col;
}
}
//回收内存
for(int i=0;i<XRow;++i)
{
delete X_Unitary[i];
}
delete X_Unitary;
for(int i=0;i<YRow;++i)
{
delete Y_Unitary[i];
}
delete Y_Unitary;
delete fMin;
delete fMax;
//--
return 0;
}
//---------------------------------------------------------------------------
double Min(double** X,int XRow,double **Y,int Col,int YIndex)
{
double result=0.0;
for(int i=0;i<XRow;++i)
{
double mink=0.0;
for(int k=0;k<Col;++k)
{
double tmp=fabs(Y[YIndex][k]-X[i][k]);
if(k==0)
{
mink = tmp;
}
else if(mink > tmp)
{
mink=tmp;
}
}
if(i==0)
{
result = mink;
}
else if(result > mink)
{
result = mink;
}
}
return result;
}
//---------------------------------------------------------------------------
double Max(double** X,int XRow,double **Y,int Col,int YIndex)
{
double result=0.0;
for(int i=0;i<XRow;++i)
{
double mink=0.0;
for(int k=0;k<Col;++k)
{
double tmp=fabs(Y[YIndex][k]-X[i][k]);
if(k==0)
{
mink = tmp;
}
else if(mink < tmp)
{
mink = tmp;
}
}
if(i==0)
{
result = mink;
}
else if(result < mink)
{
result = mink;
}
}
return result;
}
//---------------------------------------------------------------------------
//-----------------------------H----------------------------------
extern "C" __declspec(dllexport)
int __stdcall RelationGrade(double** X,int XRow,double **Y,int YRow,int Col,double E,double** R);
double Min(double** X,int XRow,double **Y,int Col,int YIndex);
double Max(double** X,int XRow,double **Y,int Col,int YIndex);
//----------------------------CPP----------------------------------
#include "RelationshipUnit.h"
#include <math.h>
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport)
int __stdcall RelationGrade(double** X,int XRow,double **Y,int YRow,int Col,double E,double** R)
{//输入参数:
// X: 子因素(二维数组)
// Y: 母因素(二维数组)
// XRow: 子因素个数
// YRow: 母因素个数
// Col: 每因素属性个数
// E: 分辨系数
//输出参数:
// R: 母因素对子因素的关联度(YRow * XRow矩阵)
//说明:
// XRow,YRow,Col限定了X,Y的大小
//返回值
// 0: 成功执行
// > 0:
// -1: 子元素首列含零值
// -2: 母元素首列含零值
// -3: 内存不足
// -4: 数据格式不对,计算过程出现分母为零
//判断子母因素数组是否符合要求——首列数据不能有零值,否则无法归一化
for(int i=0;i<XRow;++i)
{
if(X[i][0]<=0.0000001 && X[i][0] >=-0.0000001)
{
return -1;
}
}
for(int i=0;i<YRow;++i)
{
if(Y[i][0]<=0.0000001 && Y[i][0] >=-0.0000001)
{
return -2;
}
}
double **X_Unitary;//归一子因素
double **Y_Unitary;//归一母因素
try
{//数组分配一维空间
X_Unitary=new double* [XRow];
Y_Unitary=new double* [YRow];
}
catch(...)
{//内存不足
if(X_Unitary!=NULL)
{
delete X_Unitary;
X_Unitary=NULL;
}
return -3;
}
for(int i=0;i<XRow;++i)
{//子因素归一化数组分配空间
try
{
X_Unitary[i]=new double[Col];
}
catch(...)
{
for(int j=0;j<i;++j)
{
delete X_Unitary[j];
X_Unitary[j]=NULL;
}
delete X_Unitary;
X_Unitary=NULL;
delete Y_Unitary;
Y_Unitary=NULL;
return -3;
}
}
for(int i=0;i<YRow;++i)
{///母因素归一化数组分配空间
try
{
Y_Unitary[i]=new double[Col];
}
catch(...)
{
for(int j=0;j<i;++j)
{
delete Y_Unitary[j];
Y_Unitary[j]=NULL;
}
for(int j=0;j<XRow;++j)
{
delete X_Unitary[j];
X_Unitary[j]=NULL;
}
delete X_Unitary;
X_Unitary=NULL;
delete Y_Unitary;
Y_Unitary=NULL;
return -3;
}
}
//--
//归一化
for(int i=0;i<XRow;++i)
{
for(int j=0;j<Col;++j)
{
X_Unitary[i][j]=X[i][j]/X[i][0];
}
}
for(int i=0;i<YRow;++i)
{
for(int j=0;j<Col;++j)
{
Y_Unitary[i][j]=Y[i][j]/Y[i][0];
}
}
//以下省略内存分配失败判断,因为基本上不可能失败
double* fMin=new double [YRow];
double* fMax=new double [YRow];
for(int i=0;i<YRow;++i)
{
fMin[i]=Min(X_Unitary,XRow,Y_Unitary,Col,i);
fMax[i]=Max(X_Unitary,XRow,Y_Unitary,Col,i);
}
for(int j=0;j<YRow;++j)
{//计算结果
for(int i=0;i<XRow;++i)
{
R[j][i]=0.0;
for(int k=0;k<Col;++k)
{
double sub=fabs(Y_Unitary[j][k]-X_Unitary[i][k]);
double kefai;
if((sub + E*fMax[j])<=0.000001 && (sub + E*fMax[j]) >=-0.000001)
{//数据格式不符合,分母为零。
//回收内存
for(int i=0;i<XRow;++i)
{
delete X_Unitary[i];
}
delete X_Unitary;
for(int i=0;i<YRow;++i)
{
delete Y_Unitary[i];
}
delete Y_Unitary;
delete fMin;
delete fMax;
return -4;
}
kefai=(fMin[j] + E*fMax[j]) / (sub + E*fMax[j]);
R[j][i]+=kefai;
}
R[j][i]/=Col;
}
}
//回收内存
for(int i=0;i<XRow;++i)
{
delete X_Unitary[i];
}
delete X_Unitary;
for(int i=0;i<YRow;++i)
{
delete Y_Unitary[i];
}
delete Y_Unitary;
delete fMin;
delete fMax;
//--
return 0;
}
//---------------------------------------------------------------------------
double Min(double** X,int XRow,double **Y,int Col,int YIndex)
{
double result=0.0;
for(int i=0;i<XRow;++i)
{
double mink=0.0;
for(int k=0;k<Col;++k)
{
double tmp=fabs(Y[YIndex][k]-X[i][k]);
if(k==0)
{
mink = tmp;
}
else if(mink > tmp)
{
mink=tmp;
}
}
if(i==0)
{
result = mink;
}
else if(result > mink)
{
result = mink;
}
}
return result;
}
//---------------------------------------------------------------------------
double Max(double** X,int XRow,double **Y,int Col,int YIndex)
{
double result=0.0;
for(int i=0;i<XRow;++i)
{
double mink=0.0;
for(int k=0;k<Col;++k)
{
double tmp=fabs(Y[YIndex][k]-X[i][k]);
if(k==0)
{
mink = tmp;
}
else if(mink < tmp)
{
mink = tmp;
}
}
if(i==0)
{
result = mink;
}
else if(result < mink)
{
result = mink;
}
}
return result;
}
//---------------------------------------------------------------------------
#14
我自己感觉没有什么不对的地方,汗。
还有,像我这种一个函数内需要new多个数组的情况,如何能保证内存被正确的回收?假设要用到有四个数组A、B、C、D,那么:
情况1:A已经new出来了,后来new B的时候出现了错误,就要delete A然后返回
情况2:A、B已经new出来了,后来new C的时候出现了错误,就要delete A、B然后返回
情况3:A、B、C已经new出来了,后来new D的时候出现了错误,就要delete A、B、C然后返回
情况4:A、B、C都new好了,但是经过一些计算发现继续运行的条件不符合,所以就要delete A、B、C然后返回;
情况5:函数顺利运行完毕,就要delete A、B、C、D然后返回
情况N:。。。。。。。。。。。
可能有N中情况,数组可能也不止四个,如何能通过一个简便的方法来控制内存的回收?每次都是try然后在catch里面delete已经分配好的数组太繁琐了,如果是二维数组就更繁琐了。
还有,像我这种一个函数内需要new多个数组的情况,如何能保证内存被正确的回收?假设要用到有四个数组A、B、C、D,那么:
情况1:A已经new出来了,后来new B的时候出现了错误,就要delete A然后返回
情况2:A、B已经new出来了,后来new C的时候出现了错误,就要delete A、B然后返回
情况3:A、B、C已经new出来了,后来new D的时候出现了错误,就要delete A、B、C然后返回
情况4:A、B、C都new好了,但是经过一些计算发现继续运行的条件不符合,所以就要delete A、B、C然后返回;
情况5:函数顺利运行完毕,就要delete A、B、C、D然后返回
情况N:。。。。。。。。。。。
可能有N中情况,数组可能也不止四个,如何能通过一个简便的方法来控制内存的回收?每次都是try然后在catch里面delete已经分配好的数组太繁琐了,如果是二维数组就更繁琐了。
#15
導出與調用時都加上__stdcall吧,記得BCB中默認好象不是__stdcall.
習慣上寫DLL時都指定調用約定,而不用默認約定。
typedef void (__stdcall *MyCalcFunc)(double** ,int ,double**,int ,int ,double ,double**);
typedef int (__stdcall *MyInfoFunc)(HWND, HWND, LPVOID);
習慣上寫DLL時都指定調用約定,而不用默認約定。
typedef void (__stdcall *MyCalcFunc)(double** ,int ,double**,int ,int ,double ,double**);
typedef int (__stdcall *MyInfoFunc)(HWND, HWND, LPVOID);
#16
用std::vector做多維數組,沒那麼多內存問題。做一維數組更沒問題。
要控制內存的釋放時刻可考慮用 std::auto_ptr
你是寫dll , 可考慮Dll內部用vector實現,對外接口用C指針,這樣別的編譯器也能使用。
要控制內存的釋放時刻可考慮用 std::auto_ptr
你是寫dll , 可考慮Dll內部用vector實現,對外接口用C指針,這樣別的編譯器也能使用。
#17
看来是约定的问题,加上__stdcall 之后就没问题了,我看了,Builder默认是__fastcall。多谢以上各位朋友啦,特别感谢PPower(月亮光光,照地堂)。
vector我接触过,不过我不想在DLL里用,按你的说法,看样vector是没问题的,有机会我会改成vector实现的。
关于auto_ptr,我没接触过,我会去看看的!
结贴了。
vector我接触过,不过我不想在DLL里用,按你的说法,看样vector是没问题的,有机会我会改成vector实现的。
关于auto_ptr,我没接触过,我会去看看的!
结贴了。
#18
哦,Mark一下,哈哈。我写的这个DLL是个关联度分析算法,属于灰度理论,留下这些关键字以便于以后有人能搜索到:)。希望搜索到的人用到了可以通知我一下(uhian#hotmail.com),让我有点成就感,咳咳。。。。。。