2009-07-09 3 views
8

sto ottenendo questo messaggio di errore:Assunzioni di debug non riuscite! Espressione: _BLOCK_TYPE_IS_VALID

debug Asserzione non riuscita!

Espressione: _BLOCK_TYPE_US_VALID (pHead-> nBlockUse)

durante il tentativo di effettuare le seguenti operazioni

#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()); 
... 
} 

L'errore sembra essere correlato alla funzione di ordinamento. Controllo tutte le istanze del vettore delle reti e sembrano essere OK, avendo diverse sse. La cosa divertente è che ho creato un caso più semplice del codice precedente (vedi sotto) e ha funzionato senza errori. Sto distruggendo il mio cervello. Per favore aiuto.

#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

Qual è l'intero messaggio di errore? Sembra essere troncato nel titolo del tuo post. – lavinio

+1

Il tuo codice ha una tonnellata di perdite di memoria. Si chiama nuovo NN e quindi si aggiunge l'oggetto al vettore - l'oggetto viene copiato nel vettore e l'oggetto originale rimane nell'heap e non viene eliminato. È una perdita di memoria, ma non è probabile che sia la causa del problema. – sharptooth

+0

Non lo vedo nel suo esempio di codice (superiore); sembra che stia creando gli oggetti sull'heap con 'NN * net = new NN (...' e poi posizionando una copia di quel puntatore nel vettore – lavinio

risposta

11

L'affermazione _BLOCK_TYPE_IS_VALID s'incendia, quando si sovrascrive l'intestazione di un blocco allocato da new. Questo succede quando si tagliano oggetti, si utilizzano oggetti morti, ecc.

Si dovrebbe dare un'occhiata al codice completo e provare a lavorare dai dati presenti nel debugger. Questo breve frammento di codice contiene diversi 'curiosi' usi del C++, ma nessun punto ovvio in cui questo produce l'errore descritto (almeno per me).

1

Grazie a tutti. In primo luogo, ho cancellare la memoria allocata per le reti di vettore all'interno del distruttore Pop da

Pop::~Pop() 
{ 
    //nets.clear(); 
    nets.~vector<NN>(); 
} 

Il messaggio di errore non dice molto e sarei grato se qualcuno mi mostra come fare MSVC 2008 per mostrare un'informazioni più dettagliate. Qui è quello che dice (non riesco a tagliare e incollare per qualche motivo, quindi sono ridigitare esso):

Debug assertion failed! 
Programm: ... GANN.exe 
File: ... dbgedl.cpp 
line: 52 
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) 
For information how ... 

Quando si preme il debug, il compilatore mi mostra la linea 52 del file di dbgdel.cpp:

_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); 

all'interno

void operator delete (void * pUserData)

Ecco un altro del mio codice che mostra cosa succede prima che io cerco di ordinare

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

Tutto funziona correttamente fino al punto sort(). Il puntatore lSz viene utilizzato all'interno di NN per contenere il numero di nodi in ogni livello della rete neurale, ad esempio lSz [3] = {12,5,1} (12 input, un livello nascosto con 5 neuroni e un output). È usato per creare una matrice 3D dei pesi per ogni connessione della rete. Ogni rete NN (ce ne sono 100) all'interno della popolazione ha una propria matrice di pesi. Ma condividono lo stesso lSz [] e altri parametri strutturali, che sfortunatamente vengono copiati da un'altra istanza NN all'altra. Volevo usare static per dichiarare questi membri della classe condivisa, ma ciò avrebbe impedito la parallelizzazione.

0

Ho appena scoperto che se faccio costruzione Pop come questo

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

Poi tutto funziona, compreso sort(). Ma questo non funziona per me perché ora il vettore delle reti contiene la stessa istanza di NN volte popSize.L'idea era di intializzare ciascuna di queste istanze individualmente. Ogni istanza di NN si suppone di avere una propria gamma di pesi, inizializzato in modo casuale all'interno del costruttore 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

dalla mia esperienza-Questo tipo di errore potrebbe essere causato da Heap corruzione. quindi .. devi prima controllare le perdite di memoria. Se stai usando Visual Studio, usa _CrtCheckMemory().

0

A volte perché si dispone di una stringa di lunghezza x e si è accidentalmente inserita una parola più lunga ... è quello che è successo nel mio caso.

+2

questo dovrebbe essere un commento, non una risposta – wich