2009-07-09 18 views
8

estoy recibiendo este mensaje de error:¡Falló la aserción! Expresión: _BLOCK_TYPE_IS_VALID

depuración de aserción!

Expresión: _BLOCK_TYPE_US_VALID (pHead-> nBlockUse)

al tratar de hacer lo siguiente

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

El error parece estar relacionada con la función de clasificación. Compruebo todas las instancias del vector de redes y parecen estar bien, con diferentes SSE. Lo curioso es que creé un caso más simple del código anterior (ver a continuación) y funcionó sin ningún error. Estoy arruinando mi cerebro. Por favor ayuda.

#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

¿Cuál es el mensaje de error completo? Parece estar truncado en el título de su publicación. – lavinio

+1

Su código tiene un montón de pérdidas de memoria. Llama al nuevo NN y luego agrega el objeto al vector - el objeto se copia en el vector y el objeto original permanece en el montón y no lo elimina. Es una pérdida de memoria, pero no es probable que sea la causa del problema. – sharptooth

+0

No veo eso en su muestra de código (superior); parece que está creando los objetos en el montón con 'NN * net = new NN (...' y luego simplemente colocando una copia de ese puntero en el vector. – lavinio

Respuesta

11

La afirmación _BLOCK_TYPE_IS_VALID es despedido, cuando se sobrescribe la cabecera de un bloque asignado por new. Esto sucede cuando corta objetos, usa objetos muertos, etc.

Debe echar un vistazo a su código completo y tratar de trabajar a partir de los datos que tiene en su depurador. Este breve fragmento de código contiene varios usos "curiosos" de C++, pero no hay ningún punto obvio en el que esto produzca el error descrito (al menos para mí).

1

Gracias a todos. En primer lugar, puedo borrar la memoria asignada para redes vectorial en el interior del destructor Pop de

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

El mensaje de error no dice mucho y yo apreciaría si alguien me muestra cómo hacer MSVC 2008 para mostrar una información más detallada. Aquí es lo que dice (no puedo cortar y pegar, por alguna razón, así que estoy volviendo a escribirla):

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

Cuando pulso de depuración, el compilador me demuestra la línea 52 de dbgdel.cpp archivo:

_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); 

dentro

operador void borrar (void * pUserData)

Aquí está una más de mi código que muestra lo que sucede antes de tratar de resolver

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

Todo funciona correctamente hasta el punto de ordenación(). El puntero lSz se usa dentro de NN para contener el número de nodos en cada capa de la red neuronal, por ejemplo lSz [3] = {12,5,1} (12 entradas, una capa oculta con 5 neuronas y una salida). Se utiliza para crear una matriz tridimensional de los pesos para cada conexión de la red. Cada red NN (hay 100) dentro de la población tiene su propia matriz de ponderación. Pero comparten el mismo lSz [] y otros parámetros estructurales, que desafortunadamente se copian de otra instancia NN a la otra. Quería usar static para declarar estos miembros de la clase compartida, pero eso evitaría la paralelización.

0

acabo de descubrir que si hago la construcción Pop como esto

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

Entonces funciona todo, incluyendo sort(). Pero eso no funciona para mí porque ahora el vector de redes contiene la misma instancia de NN popSize veces.La idea era iniciar cada una de estas instancias individualmente. Cada instancia de NN se supone que tiene su propio conjunto de pesos, inicializado aleatoriamente dentro del constructor 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 mi experiencia- Este tipo de error puede ser causado por la corrupción del montón. entonces ... primero debes verificar si hay fugas de memoria. Si está usando Visual Studio use _CrtCheckMemory().

0

A veces es porque tiene una cadena de longitud x y accidentalmente ha puesto una palabra más larga en ella ... eso es lo que sucedió en mi caso.

+2

esto debería ser un comentario, no una respuesta – wich