我收到此错误消息:
Debug Assertion失败!
表达式:_BLOCK_TYPE_US_VALID(pHead-> nBlockUse)
尝试执行以下操作时
#include <vector>
#include <algorithm>
using namespace std;
class NN
{
public:
NN(const int numLayers,const int *lSz,const int AFT,const int OAF,const double initWtMag,const int UEW,const double *extInitWt);
double sse;
bool operator < (const NN &net) const {return sse < net.sse;}
};
class Pop
{
int popSize;
double a;
public:
Pop(const int numLayers,const int *lSz,const int AFT,const int OAF,const double initWtMag,const int numNets,const double alpha);
~Pop();
vector<NN> nets;
void GA(...);
};
Pop::Pop(const int numLayers,const int *lSz,const int AFT,const int OAF,
const double initWtMag,const int numNets,const double alpha)
{
popSize=numNets;
a=alpha;
nets.reserve(popSize);
for(int i=0;i<popSize;i++)
{
NN *net = new NN (numLayers,lSz,AFT,OAF,initWtMag,0,0);
nets.push_back(*net);
}
}
void Pop::GA()
{
...
sort(nets.begin(),nets.end());
...
}
该错误似乎与排序功能有关。我检查网络矢量的所有实例,它们似乎没问题,有不同的sse。有趣的是,我创建了一个更简单的上述代码案例(见下文),它没有任何错误。我正在破坏我的大脑。请帮忙。
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class Student
{
public:
string name;
double grade;
Student(string,double);
bool operator < (const Student &st) const {return grade < st.grade;}
};
Student::Student(string stName,double stGrade)
{
name = stName;
grade = stGrade;
}
int main()
{
vector<Student> group;
Student *st;
st = new Student("Bill",3.5);
group.push_back(*st);
st = new Student("John",3.9);
group.push_back(*st);
st = new Student("Dave",3.1);
group.push_back(*st);
sort(group.begin(),group.end());
for each(Student st in group)
cout << st.name << " " << st.grade << endl;
cin.get();
return(0);
}
答案 0 :(得分:11)
当您覆盖由new
分配的块的标头时,会触发_BLOCK_TYPE_IS_VALID断言。切片对象,使用死对象等时会发生这种情况。
您应该查看完整的代码,并尝试使用调试器中的数据。这个简短的代码片段包含了对C ++的一些“好奇”用法,但没有明显的点可以产生所描述的错误(至少对我而言)。
答案 1 :(得分:3)
根据我的经验 - 这种类型的错误可能是由堆损坏引起的。所以..你必须首先检查内存泄漏。如果您使用的是Visual Studio,请使用_CrtCheckMemory()。
答案 2 :(得分:1)
谢谢大家。首先,我通过
清除为Pop析构函数中的网络向量分配的内存Pop::~Pop()
{
//nets.clear();
nets.~vector<NN>();
}
错误消息并没有多说,如果有人向我展示如何让MSVC 2008显示更详细的信息,我将不胜感激。这就是它所说的(由于某些原因我不能剪切和粘贴它,所以我正在重新输入它):
Debug assertion failed!
Programm: ... GANN.exe
File: ... dbgedl.cpp
line: 52
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
For information how ...
当我按下debug时,编译器会显示文件dbgdel.cpp的第52行:
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
内
void operator delete(void * pUserData)
这是我的更多代码,显示在我尝试排序之前发生的事情
double Pop::GA(...)
{
for (int gen=0;gen<ngen;gen++)
{
int istart=0;
if(gen>0) istart=eliteSize;
for(int i=istart;i<popSize;i++)
nets[i].getSSE(in,tgt,ntr,discount);
for(int i=istart;i<popSize;i++)
{
cout << i << " " << nets[i].sse << endl;
}
sort(nets.begin(),nets.end());
一切正常,直到sort()点。在NN内部使用lSz指针来保持神经网络的每层中的节点数量,例如lSz [3] = {12,5,1}(12个输入,一个隐藏层具有5个神经元和一个输出)。它用于为网络的每个连接创建权重的3D数组。人口中的每个网络NN(其中有100个)都有自己的权重数组。但它们共享相同的lSz []和其他结构参数,不幸的是它们从其他NN实例复制到另一个。我想使用static来声明这些共享类成员,但这会阻止并行化。
答案 3 :(得分:0)
我刚刚发现如果我像这样做Pop结构
Pop::Pop(const int numLayers,const int *lSz,const int AFT,const int OAF,
const double initWtMag,const int numNets,const double alpha)
{
popSize=numNets;
a=alpha;
cout << "defined a\n";
nets.reserve(popSize);
NN *net = new NN (numLayers,lSz,AFT,OAF,initWtMag,0,0);
for(int i=0;i<popSize;i++)
{
//NN *net = new NN (numLayers,lSz,AFT,OAF,initWtMag,0,0);
nets.push_back(*net);
}
}
然后一切正常,包括sort()。但是,这对我不起作用,因为现在网络向量包含相同的NN popSize时间实例。这个想法是单独初始化每个实例。每个NN实例都应该有自己的权重数组,在NN构造函数中随机初始化:
NN::NN(const int numLayers,const int *lSz,const int AFT,const int OAF,const double initWtMag,
const int UEW,const double *extInitWt)
{
// set number of layers and their sizes
nl=numLayers;
ls=new int[nl];
for(int i=0;i<nl;i++) ls[i]=lSz[i];
// set other parameters
aft=AFT;
oaf=OAF;
binMid=0.0;
if(aft==0) binMid=0.5;
// allocate memory for output of each neuron
out = new double*[nl];
for(int i=0;i<nl;i++) out[i]=new double[ls[i]];
// allocate memory for weights (genes)
// w[lr #][neuron # in this lr][input # = neuron # in prev lr]
w = new double**[nl];
for(int i=1;i<nl;i++) w[i]=new double*[ls[i]];
for(int i=1;i<nl;i++) // for each layer except input
for(int j=0;j<ls[i];j++) // for each neuron in current layer
w[i][j]=new double[ls[i-1]+1]; // w[][][ls[]] is bias
// seed and assign random weights (genes)
SYSTEMTIME tStart,tCurr;
GetSystemTime(&tStart);
for(;;)
{
GetSystemTime(&tCurr);
if(tCurr.wMilliseconds!=tStart.wMilliseconds) break;
}
srand(tCurr.wMilliseconds);
int iw=0;
for(int i=1;i<nl;i++) // for each layer except input
for(int j=0;j<ls[i];j++) // for each neuron in current layer
for(int k=0;k<=ls[i-1];k++) // for each input of curr neuron incl bias
if(UEW==0) w[i][j][k]=initWtMag*2.0*(rand()/(double)RAND_MAX-0.5);
else w[i][j][k]=extInitWt[iw++];
}
答案 4 :(得分:0)
有时它是因为你有一串长度为x的字符串并且你不小心把更长的字放进去......那就是我的情况。