调试断言失败!表达式:_BLOCK_TYPE_IS_VALID

时间:2009-07-09 06:21:06

标签: c++ debugging assertions

我收到此错误消息:

  

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);
}

5 个答案:

答案 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的字符串并且你不小心把更长的字放进去......那就是我的情况。