2009-07-09 11 views
8

Ich erhalte diese Fehlermeldung:Debug-Assertion fehlgeschlagen! Expression: _BLOCK_TYPE_IS_VALID

Debug Assertion Failed!

Expression: _BLOCK_TYPE_US_VALID (pHead-> nBlockUse)

beim Versuch, die folgenden

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

der Fehler zu tun, scheint mit der Sortierfunktion zusammenzuzuhängen. Ich überprüfe alle Instanzen von Vektornetzen und sie scheinen in Ordnung zu sein, mit verschiedenen SSEs. Das Lustige ist, dass ich einen einfacheren Fall des obigen Codes erstellt habe (siehe unten) und es hat ohne Fehler funktioniert. Ich ruiniere mein Gehirn. Bitte helfen Sie.

#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

Was ist die ganze Fehlermeldung? Es scheint im Titel Ihres Beitrags abgeschnitten zu sein. – lavinio

+1

Ihr Code weist eine Menge Speicherlecks auf. Sie rufen eine neue NN auf und fügen das Objekt dann zum Vektor hinzu - das Objekt wird in den Vektor kopiert und das ursprüngliche Objekt verbleibt auf dem Heap und Sie löschen es nicht. Es ist ein Speicherleck, aber es ist wahrscheinlich nicht die Ursache des Problems. – sharptooth

+0

Ich sehe das nicht in seinem (oberen) Codebeispiel; es sieht aus wie er mit 'NN * net = new NN (...' die Objekte auf dem Heap schafft und dann nur eine Kopie dieses Zeigers in den Vektor platzieren – lavinio

Antwort

11

Die _BLOCK_TYPE_IS_VALID Behauptung wird ausgelöst, wenn Sie durch new den Header eines Block zugeordnet überschrieben. Dies passiert, wenn Sie Objekte zerlegen, tote Objekte usw. verwenden.

Sie sollten sich Ihren vollständigen Code ansehen und versuchen, mit den Daten zu arbeiten, die Sie in Ihrem Debugger haben. Dieses kurze Code-Snippet enthält mehrere "kuriose" Anwendungen von C++, aber keinen offensichtlichen Punkt, an dem dies den beschriebenen Fehler erzeugt (zumindest für mich).

1

Danke an alle. Zuerst habe ich den Speicher für Netze Vektor in der Pop destructor von

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

Die Fehlermeldung sagt nicht viel zugeteilt klar, und ich würde es begrüßen, wenn jemand zeigt mir, wie MSVC 2008, um eine ausführlichere Informationen zu zeigen. Hier ist, was es sagt (ich kann nicht geschnitten und es aus irgendeinem Grund einfügen, so dass ich es bin Abtippen):

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

Wenn ich debug drücken, wird der Compiler mir zeigt Zeile 52 der Datei dbgdel.cpp:

_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); 

innen

Operator void löschen (void * pUserData)

Hier eine meiner Code ist zu zeigen, was vor passiert, versuche ich zu sortieren

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

Alles funktioniert bis zum sort() Punkt. Der lSz-Zeiger wird innerhalb von NN verwendet, um die Anzahl der Knoten in jeder Schicht des neuronalen Netzwerks zu halten, zum Beispiel lSz [3] = {12,5,1} (12 Eingänge, eine versteckte Schicht mit 5 Neuronen und eine Ausgabe). Es wird verwendet, um ein 3D-Array der Gewichte für jede Verbindung des Netzwerks zu erstellen. Jedes Netzwerk NN (es gibt 100 von ihnen) innerhalb der Population hat sein eigenes Gewicht-Array. Aber sie teilen die gleichen LSZ [] und andere strukturelle Parameter, die leider von anderen NN-Instanzen auf die anderen kopiert werden. Ich wollte statische verwenden, um diese freigegebenen Klassenmitglieder zu deklarieren, aber das würde Parallelisierung verhindern.

0

ich gerade entdeckt, dass, wenn ich wie diese Pop Konstruktion tun

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

Dann funktioniert alles, einschließlich der sort(). Aber, das funktioniert nicht für mich, weil jetzt der Vektor der Netze die gleiche Instanz von NN popSize mal enthält.Die Idee war, jeden dieser Fälle einzeln zu initialisieren. Jede Instanz von NN soll seine eigene Reihe von Gewichten haben, zufällig innerhalb des NN-Konstruktor initialisiert:

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

von meinem Erlebnis- Diese Art von Fehler könnte durch Heap-Beschädigung verursacht werden. also .. Sie müssen zuerst auf Speicherlecks prüfen. Wenn Sie Visual Studio verwenden, verwenden Sie _CrtCheckMemory().

0

Manchmal ist es, weil Sie einen String der Länge x haben, und Sie haben setzen versehentlich ein längeres Wort hinein ... das ist, was in meinem Fall geschehen ist.

+2

Dies sollte ein Kommentar sein, keine Antwort – wich