Pregunta

He estado yendo más profundamente en C ++ recientemente y mis errores parecen llegar compleja.

Tengo un vector de objetos, cada objeto contiene un vector de flotadores. Decidí que necesitaba para crear una matriz plana adicional que contiene todos los valores de coma flotante de todos los objetos en uno. Es un poco más complejo que eso, pero la esencia del problema es que a medida que bucle a través de mis objetos de extraer los valores de coma flotante, en algún momento de mi vector de objetos se cambia, o dañado de alguna manera extraña. (Mis operaciones de lectura son todas las funciones const)

Otro ejemplo fue con MPI. Me acaba de empezar así que sólo quería para ejecutar el mismo código en dos nodos diferentes con su propia memoria y sin la transferencia de datos ocurre, todo muy sencillo. Para mi sorpresa me dieron errores de segmentación y seguimiento de las horas después, me encontré con que una asignación de una variable se ponía una variable totalmente diferente a NULL.

Así que tengo curiosidad, ¿cómo es posible que las operaciones de lectura pueden afectar mis estructuras de datos. Del mismo modo, ¿cómo puede una operación aparentemente sin relación afectar a otro. No podía esperar soluciones a mis problemas con esos breves descripciones, pero cualquier consejo será apreciado considerablemente.

Actualización: Aquí hay un segmento del código, No he puesto originalmente porque no estoy seguro de cuánto se puede extraer de ella sin entender todo el sistema.

Una cosa que me acabo de enterar de que fue que cuando dejé de asignar el valor a mi matriz plana y solo cout'ed lugar, los errores seg desaparecieron. Así que tal vez estoy declarando mi arsenal mal, pero incluso si yo era no estoy seguro de cómo afectaría el vector objeto.

void xlMasterSlaveGpuEA::FillFlatGenes() {
    int stringLength = pop->GetGenome(0).GetLength();
    for (int i=0;i<pop->GetPopSize();i++)
        for (int j=0;j<stringLength;j++)
            flatGenes[(i*stringLength)+j]<< pop->GetGenome(i).GetFloatGene(j);
}

float xlVectorGenome::GetFloatGene(unsigned int i) const {
    return GetGene(i);
}

mi matriz plana es una función miembro

float * flatFitness;

initailsed en el constructor de esta manera:

flatFitness = new float(popSize);

Actualización 2:

Sólo quiero señalar que los dos ejemplos anteriores no están relacionados, el primero no es multiproceso. El segundo ejemplo de MPI es técnicamente, pero MPI se distribuye la memoria y me trató deliberadamente la implementación más sencilla de lo que podía pensar, que es ambas máquinas que ejecutan código de forma independiente. Sin embargo, hay un detalle adicional, puse en un condtional diciendo

if node 1 then do bottom half of loop

if node 1 then do top half

Una vez más la memoria debe ser aislado, deberían estar trabajando como si no saben nada el uno del otro .. pero retirar esta condicional y haciendo ambos bucles hacen todos los cubos, elimina el error

¿Fue útil?

Solución

Esto no es un constructor array:

float * flatFitness;
flatFitness = new float(popSize);

Estás creando un flotador en el montón aquí, inicializado con el valor popSize. Si quieres una serie de flotadores es necesario utilizar soportes en lugar de paréntesis:

float *flatFitness = new float[popSize];

Esto podría ser fácilmente causando los problemas que usted describe. Además, recuerda al crear matrices, es necesario eliminar el uso de delete [] (con el tiempo):

delete [] flatFitness;

Si sólo utiliza delete, podría funcionar, pero el comportamiento no está definido.

Si desea evitar el uso de la sintaxis de matrices por completo, por qué no usar std::vector? Puede crear un vector de elementos POPSIZE como esta:

#include <vector>

std::vector<float> flatFitness(popSize);

Esto se libera automáticamente cuando esté fuera de su alcance, por lo que no tiene que preocuparse de new o delete.

Actualizar (re: comentario): Si ya está utilizando std::vectors en otras partes de su código, echar un vistazo a std::vector::swap(). Es posible que pueda evitar copiar cosas por completo y sólo intercambiar un par de vectores de ida y vuelta entre el almacenamiento en búfer para CUDA y el procesamiento que estás haciendo aquí.

Otros consejos

Me sospecha que tiene problemas de corrupción de memoria multi-threading o que no son conscientes. El comportamiento que se describe no es cualquier tipo de norma, por diseño, el comportamiento deseable.

jeffamaphone puede estar en lo cierto que este es un tema de roscado. Otra posibilidad es que los objetos que se está leyendo ya han sido eliminados. A continuación, se lee en una dirección no válida. También es posible que las estructuras de datos que escribe el usuario en en este momento se almacenan en la misma ubicación que los vectores anteriormente ocupadas. Esto daría como resultado el comportamiento que usted describe.

Editar (basado en la actualización):

Esto puede ser defectuosa: stringLength se inicializa fuera del lazo externo, pero parece que necesita ser actualizado durante ese bucle exterior:

int stringLength = pop->GetGenome(0).GetLength();
for (int i=0;i<pop->GetPopSize();i++)
    for (int j=0;j<stringLength;j++)
        flatGenes[(i*stringLength)+j]<< pop->GetGenome(i).GetFloatGene(j);

solución sugerida:

for (int i=0;i<pop->GetPopSize();i++) {
    int stringLength = pop->GetGenome(i).GetLength();
    for (int j=0;j<stringLength;j++) {
        flatGenes[(i*stringLength)+j]<< pop->GetGenome(i).GetFloatGene(j);
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top