Pergunta

Eu tenho ido mais fundo em C ++ recentemente e meus erros parecem ter complexa.

Eu tenho um vetor de objetos, cada objeto contém um vetor de carros alegóricos. Decidi I necessário para criar uma nova matriz plana que contém todos os valores de todos os objectos flutuantes em um. É um pouco mais complexo do que isso, mas a essência do problema é que, como eu loop através de meus objetos de extrair os valores float, em algum momento o meu vetor de objetos é alterado, ou corrompido de alguma forma estranha. (Meus operações de leitura são todas as funções const)

Outro exemplo foi com MPI. Eu estava apenas começando, então eu só queria correr exatamente o mesmo código em dois nós diferentes com sua própria memória e sem acontecimento transferência de dados, tudo muito simples. Para minha surpresa eu tenho de segmentação erros e depois de horas de monitoramento, descobri que uma atribuição de uma variável foi definir uma variável totalmente diferente de NULL.

Então, eu sou curioso, como é possível que as operações de leitura pode afetar minhas estruturas de dados. Da mesma forma como pode uma operação aparentemente não relacionados afetar o outro. Eu não poderia esperar soluções para os meus problemas com essas descrições breves, mas qualquer conselho será muito apreciada.

Update: Aqui é um segmento do código, eu não postar originalmente porque eu não tenho certeza de quanto pode ser extraído a partir dele sem compreender todo o sistema.

Uma coisa que eu só descobri embora foi que quando eu parei de atribuir o valor para minha matriz plana e apenas cout'ed em vez disso, os erros seg desapareceu. Então, talvez eu estou declarando minha matriz errado, mas mesmo se eu fosse eu não tenho certeza como isso afetaria o vetor 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);
}

minha matriz simples é uma função membro

float * flatFitness;

initailsed no construtor assim:

flatFitness = new float(popSize);

Update 2:

Eu só quero salientar que os dois exemplos acima não estão relacionados, o primeiro não é multi threaded. O segundo exemplo MPI é tecnicamente, mas MPI é distribuído memória e eu deliberadamente tentado a implementação simples mais que eu poderia pensar, que é ambas as máquinas que executam o código de forma independente. Há, porém, um detalhe extra, eu coloquei em um ditado condtional

if node 1 then do bottom half of loop

if node 1 then do top half

Mais uma vez a memória devem ser isolados, eles devem estar trabalhando como se eles não sabem nada sobre o outro .. mas querer retirar esta condicional e fazer ambos os loops fazer todos os cubos, elimina o erro

Foi útil?

Solução

Este não é um construtor de matriz:

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

Você está criando uma bóia na pilha aqui, inicializada com valor popSize. Se você quer uma variedade de carros alegóricos você precisa usar colchetes em vez de parênteses:

float *flatFitness = new float[popSize];

Isto poderia facilmente estar causando os problemas que você descreve. Além disso, lembre-se quando você criar matrizes, você precisa excluir usando delete [] (eventualmente):

delete [] flatFitness;

Se você usar apenas delete, ele poderia funcionar, mas o comportamento é indefinido.

Se você quiser evitar o uso de sintaxe de matriz completamente, por que não usar std::vector? Você pode criar um vetor de elementos popSize assim:

#include <vector>

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

Esta será liberado automaticamente quando ele ficar fora do escopo, para que você não precisa se preocupar com new ou delete.

Update (re: comentário): Se você já está usando std::vectors outro lugar no seu código, dê uma olhada std::vector::swap(). Você pode ser capaz de evitar a cópia de coisas completamente e apenas trocar um vetores casal e para trás entre buffer para CUDA eo processamento que está fazendo aqui.

Outras dicas

Eu suspeito que você tem problemas de corrupção de memória multi-threading ou você não está ciente. O comportamento que você descreve não é qualquer tipo de by-design, o comportamento padrão, desejável.

jeffamaphone pode estar certo que este é um problema de segmentação. Outra possibilidade é que os objetos que você está lendo já ter sido eliminada. Você seria, então, a leitura de um endereço inválido. Também é possível que as estruturas de dados que você está escrevendo para, neste momento são armazenados no mesmo local que os vetores anteriormente ocupado. Isso resultaria no comportamento que você está descrevendo.

Editar (com base na sua atualização):

Esta pode estar com defeito: stringLength está fora inicializado do laço externo, mas parece que ele precisa ser atualizado durante esse loop externo:

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

correção 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top