C ++ : 읽기 데이터가 메모리에 영향을 줄 수있는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/795496

  •  18-09-2019
  •  | 
  •  

문제

나는 최근에 C ++에 더 깊이 들어가고 내 버그는 복잡해 보인다.

나는 물체의 벡터가 있고 각 물체에는 플로트 벡터가 포함되어 있습니다. 나는 모든 객체의 모든 플로트 값을 하나로 포함하는 추가 플랫 배열을 만들어야한다고 결정했습니다. 그것보다 조금 더 복잡하지만 문제의 요점은 플로트 값을 추출하는 객체를 통해 루프를 통해 객체의 벡터가 변경되거나 이상한 방식으로 손상된다는 것입니다. (내 읽기 작업은 모두 const 함수입니다)

또 다른 예는 MPI였습니다. 방금 시작하고 있었기 때문에 자체 메모리가 있고 데이터 전송이 발생하지 않고 매우 간단한 두 개의 다른 노드에서 정확히 동일한 코드를 실행하고 싶었습니다. 놀랍게도 세분화 오류가 발생했고 시간 추적 후 하나의 변수를 하나의 할당하면 완전히 다른 변수를 null로 설정하고 있음을 알았습니다.

따라서 궁금합니다. 읽기 작업이 내 데이터 구조에 영향을 줄 수있는 방법은 무엇입니까? 마찬가지로 겉보기에 관련이없는 운영이 다른 작업에 어떻게 영향을 미칠 수 있는지. 나는 그 간단한 설명에 대한 나의 문제에 대한 해결책을 기대할 수 없었지만 어떤 조언에 큰 감사를 표할 것입니다.

업데이트 : 여기에 코드의 세그먼트가 있습니다. 원래 전체 시스템을 이해하지 않고 얼마나 많은 것을 추출 할 수 있는지 확실하지 않기 때문에 원래 게시하지 않았습니다.

내가 방금 발견 한 한 가지는 평평한 배열에 값을 할당하지 않았고 대신 Cout을 대신했을 때 SEG 오류가 사라 졌다는 것입니다. 그래서 아마도 나는 배열을 잘못 선언하고 있지만, 내가 있었더라도 그것이 객체 벡터에 어떤 영향을 미칠지 확실하지 않습니다.

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

내 평평한 배열은 멤버 기능입니다

float * flatFitness;

SO처럼 생성자에 시작되었습니다.

flatFitness = new float(popSize);

Update 2:

위의 두 예제는 관련이 없으며 첫 번째 예는 멀티 스레드가 아닙니다. 두 번째 MPI 예제는 기술적으로이지만 MPI는 분산 메모리이며 고의적으로 생각할 수있는 가장 간단한 구현을 시도했습니다. 이는 코드를 독립적으로 실행하는 머신입니다. 그러나 추가 세부 사항이 하나 있습니다.

if node 1 then do bottom half of loop

if node 1 then do top half

다시 한 번 메모리를 격리해야합니다. 그들은 서로에 대해 아무것도 모르는 것처럼 작동해야합니다. 그러나이 조건부를 제거하고 두 루프를 모두 큐브로 만들고 오류를 제거합니다.

도움이 되었습니까?

해결책

이것은 배열 생성자가 아닙니다.

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

여기 힙에 플로트 하나를 만들고 값으로 초기화되었습니다. popSize. 플로트 배열을 원한다면 괄호 대신 괄호를 사용해야합니다.

float *flatFitness = new float[popSize];

이것은 당신이 설명하는 문제를 쉽게 일으킬 수 있습니다. 또한 배열을 만들 때를 기억하면 사용을 삭제해야합니다. delete [] (결국):

delete [] flatFitness;

만 사용하는 경우 delete, 그것은 작동 할 수 있지만 행동은 정의되지 않습니다.

배열 구문을 완전히 사용하지 않으려면 사용하지 않는 이유는 무엇입니까? std::vector? 다음과 같은 팝 사이즈 요소의 벡터를 만들 수 있습니다.

#include <vector>

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

범위가 떨어지면 자동으로 해제되므로 걱정할 필요가 없습니다. new 또는 delete.

업데이트 (Re : 댓글) : 이미 사용중인 경우 std::vectors 코드의 다른 곳에서는 살펴보십시오 std::vector::swap(). 당신은 물건을 완전히 복사하지 않고 Cuda를 위해 버퍼링과 여기에서 수행하는 처리 사이에서 몇 개의 벡터를 앞뒤로 교환 할 수 있습니다.

다른 팁

나는 당신이 알지 못하는 멀티 스레딩 또는 메모리 부패 문제가 있다고 생각합니다. 당신이 설명하는 행동은 어떤 종류의 표준, 신분, 바람직한 행동이 아닙니다.

Jeffamaphone은 이것이 스레딩 문제라는 것이 옳을 수 있습니다. 또 다른 가능성은 당신이 읽고있는 객체가 이미 삭제되었을 것입니다. 그런 다음 유효하지 않은 주소에서 읽을 것입니다. 이 시점에 쓰고있는 데이터 구조는 이전에 벡터가 이전에 점유했던 동일한 위치에 저장 될 수도 있습니다. 이것은 당신이 묘사하는 행동을 초래할 것입니다.

편집하다 (업데이트에 따라) :

이것은 결함이있을 수 있습니다. stringLength 외부 루프 외부에서 초기화되지만 해당 외부 루프 중에 업데이트 해야하는 것처럼 보입니다.

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

제안 된 수정 :

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);
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top