7

我收到此错误消息:

调试断言失败!

表达式:_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());
...
}

该错误似乎与排序功能有关。我检查了 nets 向量的所有实例,它们似乎没问题,具有不同的 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);
}
4

5 回答 5

11

_BLOCK_TYPE_IS_VALID 断言在您覆盖由new. 当您切片对象、使用死对象等时会发生这种情况。

您应该查看完整的代码,并尝试使用调试器中的数据进行工作。这个简短的代码片段包含 C++ 的几个“奇怪”用法,但没有明显的点会产生所描述的错误(至少对我而言)。

于 2009-07-09T09:41:39.967 回答
3

根据我的经验 - 这种类型的错误可能是由堆损坏引起的。所以..您必须首先检查内存泄漏。如果您使用的是 Visual Studio,请使用 _CrtCheckMemory()。

于 2012-01-12T19:29:10.463 回答
1

谢谢大家。首先,我清除在 Pop 析构函数中为 nets 向量分配的内存

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

当我按下调试时,编译器显示文件 dbgdel.cpp 的第 52 行:

_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));

里面

无效运算符删除(无效 *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() 点。lSz 指针在 NN 内部用于保存神经网络每一层的节点数,例如 lSz[3]={12,5,1}(12 个输入,一个隐藏层,5 个神经元和一个输出)。它用于为网络的每个连接创建权重的 3D 数组。Population 中的每个网络 NN(有 100 个)都有自己的权重数组。但是它们共享相同的 lSz[] 和其他结构参数,不幸的是这些参数从其他 NN 实例复制到另一个。我想使用静态来声明这些共享类成员,但这会阻止并行化。

于 2009-07-09T15:46:30.127 回答
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()。但是,这对我不起作用,因为现在 nets 向量包含相同的 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++];
}
于 2009-07-09T16:00:38.413 回答
0

有时是因为您有一个长度为 x 的字符串,并且您不小心在其中输入了一个较长的单词……这就是我的情况。

于 2012-09-07T12:32:58.360 回答