2009-07-09 6 views
8

Je reçois ce message d'erreur:Échec de l'assommage de débogage! Expression: _BLOCK_TYPE_IS_VALID

Debug Assertion a échoué!

Expression: _BLOCK_TYPE_US_VALID (pHead-> nBlockUse)

tout en essayant de faire ce qui suit

#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'erreur semble être lié à la fonction de tri. Je vérifie toutes les instances de vecteur de filets et ils semblent être OK, ayant des sse différents. La chose amusante est que j'ai créé un cas plus simple du code ci-dessus (voir ci-dessous) et cela a fonctionné sans aucune erreur. Je détruis mon cerveau. S'il vous plaît aider.

#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

Quel est le message d'erreur complet? Il semble être tronqué dans le titre de votre publication. – lavinio

+1

Votre code a une tonne de fuites de mémoire. Vous appelez le nouveau NN, puis ajoutez l'objet au vecteur - l'objet est copié dans le vecteur et l'objet d'origine reste sur le tas et vous ne le supprimez pas. C'est une fuite de mémoire, mais ce n'est pas susceptible d'être la cause du problème. – sharptooth

+0

Je ne le vois pas dans son exemple de code (supérieur); on dirait qu'il crée les objets sur le tas avec NN * net = new NN (... 'et ensuite il place simplement une copie de ce pointeur dans le vecteur – lavinio

Répondre

11

L'affirmation _BLOCK_TYPE_IS_VALID perd son travail, quand vous écrasez l'en-tête d'un bloc attribué par new. Cela se produit lorsque vous découpez des objets, utilisez des objets morts, etc.

Vous devriez jeter un coup d'œil à votre code complet et essayer de travailler à partir des données que vous avez dans votre débogueur. Cet extrait de code court contient plusieurs utilisations «curieuses» de C++, mais aucun point évident à partir duquel cela produit l'erreur décrite (au moins pour moi).

1

Merci à tous. Tout d'abord, j'effacer la mémoire allouée pour les filets vecteur dans la destructor Pop par

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

Le message d'erreur ne dit pas grand-chose et j'apprécierait si quelqu'un me montre comment faire MSVC 2008 pour montrer une information plus détaillée. Voici ce qu'il dit (je ne peux pas couper et coller pour une raison quelconque, je suis le retapant):

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

Lorsque je presse debug, le compilateur me montre la ligne 52 du fichier dbgdel.cpp:

_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); 

intérieur

void operator delete (void * pUserData)

est ici un plus de mon code montrant ce qui se passe avant d'essayer de trier

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

Tout fonctionne correctement jusqu'au point de tri(). Le pointeur lSz est utilisé à l'intérieur de NN pour contenir le nombre de nœuds dans chaque couche du réseau neuronal, par exemple lSz [3] = {12,5,1} (12 entrées, une couche cachée avec 5 neurones et une sortie). Il est utilisé pour créer un tableau 3D des poids pour chaque connexion du réseau. Chaque réseau NN (il y en a 100) à l'intérieur de la population a son propre réseau de poids. Mais ils partagent le même lSz [] et d'autres paramètres structurels, qui malheureusement sont copiés d'une instance NN à l'autre. Je voulais utiliser static pour déclarer ces membres de classe partagés, mais cela empêcherait la parallélisation.

0

Je viens de découvrir que si je fais la construction Pop comme ce

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

Ensuite, tout fonctionne, y compris sort(). Mais, cela ne marche pas pour moi parce que maintenant le vecteur de filets contient la même instance de NN popSize fois.L'idée était d'initialiser chacun de ces cas individuellement. Chaque instance de NN est censé avoir sa propre gamme de poids, initialisé au hasard dans le constructeur 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

de mon expérience-Ce type d'erreur peut être causée par la corruption Heap. donc .. vous devez d'abord vérifier les fuites de mémoire. Si vous utilisez Visual Studio, utilisez _CrtCheckMemory().

0

Parfois, c'est parce que vous avez une chaîne de longueur x et vous avez accidentellement mis un mot plus long ... c'est ce qui est arrivé dans mon cas.

+2

cela devrait être un commentaire, pas une réponse – wich