2009-07-09 19 views
8

otrzymuję komunikat o błędzie:Asercja debugowania nie powiodła się! Wyrażenie: _BLOCK_TYPE_IS_VALID

Debug Assertion failed!

Expression: _BLOCK_TYPE_US_VALID (pHead-> nBlockUse)

starając się zrobić następujące

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

Błąd wydaje się być związane z funkcją sortowania. Sprawdzam wszystkie przypadki sieci wektorów i wydają się być w porządku, mając różne sse. Zabawne jest to, że stworzyłem prostszy przypadek powyższego kodu (patrz poniżej) i zadziałało bez błędów. Zniszczę mój mózg. Proszę pomóż.

#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

Co to jest cały komunikat o błędzie? Wygląda na okrojony w tytule Twojego posta. – lavinio

+1

Twój kod zawiera mnóstwo wycieków pamięci. Wywołujesz nowe NN, a następnie dodajesz obiekt do wektora - obiekt zostanie skopiowany do wektora, a oryginalny obiekt pozostanie na stercie i nie zostanie usunięty. Jest to wyciek pamięci, ale najprawdopodobniej nie jest przyczyną problemu. – sharptooth

+0

Nie widzę tego w jego (górnym) przykładzie kodu; wygląda na to, że tworzy obiekty na stercie za pomocą 'NN * net = new NN (...' a następnie po prostu umieszczenie kopii tego wskaźnika w wektorze – lavinio

Odpowiedz

11

_BLOCK_TYPE_IS_VALID twierdzenie zostaje zwolniony, kiedy zastąpić nagłówek bloku przydzielone przez new. Dzieje się tak, gdy dzielisz obiekty, używasz martwych obiektów itd.

Powinieneś rzucić okiem na swój kompletny kod i spróbować pracować z danymi, które masz w swoim debugerze. Ten krótki fragment kodu zawiera kilka "ciekawych" zastosowań języka C++, ale nie ma żadnego oczywistego punktu, w którym powoduje to opisany błąd (przynajmniej dla mnie).

1

Dziękuję wszystkim. Po pierwsze, wyczyścić pamięć przydzieloną dla siatek wektorem wewnątrz destruktora pop

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

Komunikat o błędzie nie mówi dużo i byłbym wdzięczny jeśli ktoś pokazuje mi jak zrobić MSVC 2008, aby pokazać bardziej szczegółowe informacje. Oto co mówi (nie mogę wyciąć i wkleić go z jakiegoś powodu, więc jestem przepisywania go):

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

Po naciśnięciu debug kompilator pokazuje mi linia 52 plików dbgdel.cpp:

_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); 

wewnątrz

void operator delete (void * pUserData)

Oto bardziej mojego kodu pokazuje, co dzieje się przed próbuję uporządkować

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

Wszystko działa poprawnie aż do punktu sort(). Wskaźnik LSz jest używany wewnątrz NN do przechowywania liczby węzłów w każdej warstwie sieci neuronowej, na przykład lSz [3] = {12,5,1} (12 wejść, jedna ukryta warstwa z 5 neuronami i jedno wyjście). Służy do tworzenia trójwymiarowej tablicy wag dla każdego połączenia sieci. Każda sieć NN (jest ich 100) wewnątrz Populacji ma własną tablicę wagi. Ale mają one ten sam lSz [] i inne parametry strukturalne, które niestety są kopiowane z innych instancji NN do innych. Chciałem użyć statycznego, aby zadeklarować tych współdzielonych członków klasy, ale to uniemożliwiłoby równoległość.

0

Właśnie odkryłem, że jeśli to zrobię budowę Pop jak ten

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

Potem wszystko działa, w tym rodzaju(). Ale to nie działa dla mnie, ponieważ teraz wektor sieci zawiera tę samą instancję czasów NNPize.Pomysł polegał na zainicjowaniu każdej z tych instancji indywidualnie. Każda instancja NN ma mieć swoją własną tablicę ciężarkami, losowo zainicjowany wewnątrz konstruktora 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

z mojego doświadczenie-Ten typ błędu może być spowodowane uszkodzeniem stosu. więc musisz najpierw sprawdzić, czy nie ma wycieków pamięci. Jeśli używasz Visual Studio, użyj _CrtCheckMemory().

0

Czasami dlatego, że masz ciąg długości x i przypadkowo włożyłeś do niego dłuższe słowo ... To się stało w moim przypadku.

+2

to powinien być komentarz, a nie odpowiedź – wich

Powiązane problemy