2009-07-09 4 views
8

Я получаю сообщение об ошибке:Ошибка отладки! Выражение: _BLOCK_TYPE_IS_VALID

Debug Assertion Failed!

Expression: _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's. Самое забавное, что я создал более простой пример вышеупомянутого кода (см. Ниже), и он работал без ошибок. Я разрушаю свой мозг. Пожалуйста помоги.

#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

В чем все сообщение об ошибке? Кажется, он усечен в заголовке вашего сообщения. – lavinio

+1

Ваш код имеет массу утечек памяти. Вы вызываете новый NN, а затем добавляете объект к вектору - объект копируется в вектор, а исходный объект остается в куче, и вы его не удаляете. Это утечка памяти, но это вряд ли может быть причиной проблемы. – sharptooth

+0

Я не вижу этого в его (верхнем) образце кода; похоже, он создает объекты в куче с помощью 'NN * net = new NN (...', а затем просто помещает копию этого указателя в вектор. – lavinio

ответ

11

_BLOCK_TYPE_IS_VALID утверждение увольняют, когда вы перезаписать заголовок блока, выделенного new. Это происходит, когда вы срезаете объекты, используете мертвые объекты и т. Д.

Вы должны взглянуть на свой полный код и попытаться работать с данными, содержащимися в вашем отладчике. Этот короткий фрагмент кода содержит несколько «любопытных» использования C++, но нет очевидной точки, в которой это создает описанную ошибку (по крайней мере для меня).

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

Когда я нажимаю отладки, компилятор показывает мне строки 52 из файла dbgdel.cpp:

_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()); 

Все работает должным образом до точки сортировки(). Указатель lSz используется внутри NN для хранения количества узлов в каждом слое нейронной сети, например lSz [3] = {12,5,1} (12 входов, один скрытый слой с 5 нейронами и один выход). Он используется для создания 3D-массива весов для каждого соединения сети. Каждая сеть NN (их 100) внутри Населения имеет собственный весовой массив. Но они имеют одни и те же lSz [] и другие структурные параметры, которые, к сожалению, копируются из другого экземпляра NN в другой. Я хотел использовать static для объявления этих общих классов, но это предотвратит распараллеливание.

0

Я только что обнаружил, что если я поп строительство как этот

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

Тогда все работает, в том числе рода(). Но это не работает для меня, потому что теперь вектор сетей содержит один и тот же экземпляр 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++]; 
} 
3

из моего опыта-Этот тип ошибки может быть вызван повреждением кучи. поэтому .. вы должны сначала проверить утечку памяти. Если вы используете Visual Studio, используйте _CrtCheckMemory().

0

Иногда это потому, что у вас есть длина длины x, и вы случайно положили в нее более длинное слово ... вот что произошло в моем случае.

+2

это должен быть комментарий, а не ответ – wich

Смежные вопросы