【问题标题】:Debug Assertion Failed! Expression: _BLOCK_TYPE_IS_VALID [closed]调试断言失败!表达式:_BLOCK_TYPE_IS_VALID [关闭]
【发布时间】:2010-11-09 06:47:15
【问题描述】:

我收到此错误消息:

调试断言失败!

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

【问题讨论】:

标签: c++ debugging assertions


【解决方案1】:

当您覆盖new 分配的块的标头时,_BLOCK_TYPE_IS_VALID 断言会被触发。当您切片对象、使用死对象等时会发生这种情况。

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      谢谢大家。首先,我清除了在 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));
      

      里面

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

      【讨论】:

        【解决方案4】:

        我刚刚发现,如果我像这样进行 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++];
        }
        

        【讨论】:

          【解决方案5】:

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

          【讨论】:

          • 这应该是评论,而不是答案
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-01-11
          • 1970-01-01
          • 2013-06-06
          • 2018-03-23
          • 1970-01-01
          • 1970-01-01
          • 2016-08-01
          相关资源
          最近更新 更多