2013-08-02 4 views
2

particle 클래스의 일부 값을 올바르게 전달하는 오버로드 된 = 연산자가 있지만 다른 값은 전달하지 못했습니다. 온라인으로 문제를 해결했으며이 문제와 직접 관련이있는 것을 찾을 수 없습니다. C++에서 유능한 동료가 도움을 줄 수 없으며 여기에 게시 할 것을 권장합니다. 어떤 도움이라도 대단히 감사하겠습니다. width, height, wrap, particlenarray에 대한포인터 값이 오버로드 된 같음 연산자에 올바르게 전달되지 않음 (C++)

모든 값은 완벽하게 통과했다. 그러나 xpos, ypos, xvelyvel의 값이 잘못된 값으로 전달되었습니다. xposypos의 경우 11 번째 요소가 모두 올바르게 전달되었지만 다른 모든 요소는 0과 같습니다. 나는이 값들 중 어느 것도 0이 아니길 기대한다. main에서 즉시 진행하는 gen1 = gen0; 작업에서 gen0에 대한 참조 해제 된 값이 모두 정확했습니다. 나는 그들이 어떻게 든 올바르게 통과되지 않았다고 추정한다. 필요한 경우 더 많은 코드/정보를 기꺼이 게시 할 것입니다. 다시 한번, 모든 통찰력은 깊이 감사 할 것입니다. 고맙습니다.

관련 코드 : 과부하 = 연산자의

class particle{    
private: 
    int* xpos; 
    int* ypos; 
    int* xvel; 
    int* yvel; 
    int* array;    
    int width; 
    int height; 
    int wrap; 
    int particlen; 
public: 
    void operator=(const particle&); 
} 

관련 부품 : 주요의

void particle::operator=(const particle &current){ 
    int a,b,i,j; 
    width = current.width; 
    height = current.height; 
    wrap = current.wrap; 
    particlen = current.particlen; 
    array = new int[width*height]; 
    xpos = new int[particlen]; 
    ypos = new int[particlen]; 
    xvel = new int[particlen]; 
    yvel = new int[particlen]; 

    for(a=0; a<height; a++){ 
     for(b=0; b< width; b++){ 
     this->array[a*width + b] = current.array[a*width + b]; 
     } 
    } 

for(i = 0; i < particlen; i++){ 
    this->xpos[i] = current.xpos[i]; 
    this->ypos[i] = current.ypos[i]; 
    this->xvel[i] = current.xvel[i]; 
    this->yvel[i] = current.yvel[i]; 
} 

관련 부품 :

int main(){ 
    particle gen0,gen1; 
    gen1 = gen0; 
} 

Sehe의 제안으로, 내 코드를 편집했다. 그러나, 나는 지금 가장 간단한 명령으로 메모리 할당 문제를 얻고있다. < < 연산자를 사용하면 내 main에서 호출 된 첫 번째 연산에서 배열 변수를 파일의 읽기에있는 정수와 같게 설정할 수 없습니다. 첫 번째 출력 라인이 인쇄 할 때 파일이 읽기 쉽다는 것을 확실히 알고 있습니다. 그런 다음 array[i*width + j] = k;에 세그먼트 오류 11이 발생합니다. GDB는 출력을 출력합니다 : 프로그램 수신 신호 EXC_BAD_ACCESS, 메모리에 접근 할 수 없습니다. 이유 : 686 686 배열 [내가 * 너비 + J = K : 이전의 typedef 1 vector.cpp에서 입자의 0x0000000000000000 0x000000010001c4f4 :: 연산자 < < (이 0x7fff5fbfcb08 파일 = 0x7fff5fbffa90 "100100을"=) 주소 KERN_INVALID_ADDRESS ;

나는 온라인으로 벡터 라이브러리에 대한 올바른 용어를 찾아 보았고 나의 구문이 맞다고 생각했다. 어떤 아이디어?

업데이트 (동부 표준시 09시 8월 2일) 나는 여전히 NULL 포인터에 문제가 있어요

. 입자 :: 연산자 < < (이 0x7fff5fbfcb08, 파일 = 0x7fff5fbffa90 "5040"를 =)에서 0x0000000000000000 0x000000010001d807 전 타입 정의 1 vector.cpp에서 : 주소

KERN_INVALID_ADDRESS : 디버깅 GDB를 사용할 때, 나는 메시지를 수신 688 688 어레이 [(i * 폭 + j)] = k;

나는 NULL 포인터에 대한 경험이 거의 없다. 왜 이런 일이 일어나는 지에 대한 제안과 그것을 고치는 방법? 여기에 관련 코드 나는이 긴 알고 있지만, 나는 이것이 내가 제공 할 수있는 최소한의 정보입니다 생각 (전체 코드는 약 900 라인이다)

class particle{    
private: 
    std::vector<int> xpos; 
    std::vector<int> ypos; 
    std::vector<int> xvel; 
    std::vector<int> yvel; 
    std::vector<int> array; 
    int width;  
    int height;  
    int wrap;  
    int particlen; // number of particles read in 
public: 
    void operator<<(particle); 
    void Collision(int, int, particle); 
    void operator>>(char*); 
    void operator<<(char*); 
}; 

void particle::operator<<(char* file) // Reads initial input file 
{ 
ifstream in_file; 
in_file.open(file); // open the file 
int i,j,k; 
} 
in_file >> width >> height >> wrap >> particlen; 
    for(i=0; i<height; i++){ 
     for(j=0; j< width; j++){ 
      in_file >> k; 
      array[i*width + j] = k; // This is line 688 which GDB references 
     } 
    } 
} 

void particle::operator<<(particle current){ 
int i,k,j,l; 

for(k = 0; k < height*width; k++) 
{ 
    array[k] = 0; 
} 

k = 0; 

for(i=0; i < particlen; i++) 
{ 
    cout << "Current x pos is" << current.xpos[i] << endl; 
} 

for(i=0; i < particlen; i++) 
{ 

    if(array[ (current.ypos[i]-1)*width + (current.xpos[i] - 1) ] == 0) 
    { 
    //cout << "Current X position[" << i << "] is" << current.xpos[i] << endl; 
     xpos[i] = current.xpos[i] + (current.xvel[i])*timeinc; 
     if(xpos[i] > width) xpos[i] = xpos[i] - width; 
     ypos[i] = current.ypos[i] + (current.yvel[i])*timeinc; 
     if(ypos[i] > width) ypos[i] = ypos[i] - height; 

    //cout << "Next X position[" << i << "] is" << xpos[i] << endl; 
    } 

    if(array[ (current.ypos[i]-1)*width + (current.xpos[i] - 1) ] > 1 && current.JC[i] != 1) 
    { 
     for(l=i+1; l < particlen; l++) 
     { 
      if(current.xpos[l] == current.xpos[i] && current.ypos[l] == current.ypos[i] && current.JC[l] != 1) 
      { 
      Collision(i,l,current); 
      } 
     } 
    } 
} 

for(i=0; i < particlen; i++) 
{ 
    array[ (xpos[i]-1)*width + (ypos[i]-1) ] = 1; 
} 
Display();} 

int main() 
{ 
    char filename[256]; 
    particle gen0, gen1; 
    gen0 << filename; 
    gen1 = gen0; 
    gen0 << gen1; // Calculates the next state of gen0, based on the values in gen1. 
} 

입니다.아마도 문제는 gen0 << gen1 연산자와 같아서 메서드를 포함 시켰습니다. 내가 코멘트에 암시처럼

+0

이것은 보장 된 메모리 누수입니다. 당신은 원래의 배열을 삭제하지 않습니다. –

+0

@OliCharlesworth 역전 된 것으로 의심됩니다 : 복사 생성자의 포인터를 복사하는 것이 부족하다고 생각되지만 한 인스턴스에서 해제됩니다. – sehe

+1

포인터 대신'동적 배열'에'std :: vector '을 사용하십시오. 당신은 단지 문제를 요구하고 있습니다. – Casey

답변

2

는 99 % 특히, 당신은 할당 연산자를 가지고 있지만 복사 생성자가 시야에 없다 당신이 세 가지

의 규칙을 위반하고 말한다. 이는 복사 된 경우 배열 포인터가 "불법적으로"공유 될 수 있음을 의미 할 수 있습니다. 나는 또한 당신이 그 배열을 (한 인스턴스에서) 삭제하므로 어 큐브 다른 인스턴스로 복사 된 배열을 무효로 어딘가에 있다고 가정합니다. 처음에 수동 메모리 관리를 피하여

수정을 :

#include <vector> 

class particle{    
    std::vector<int> xpos; 
    std::vector<int> ypos; 
    std::vector<int> xvel; 
    std::vector<int> yvel; 
    std::vector<int> array;    
    int width; 
    int height; 
    int wrap; 
    int particlen; // or use `xpos.size()` e.g. 
}; 

int main() 
{ 
    particle gen0,gen1; 
    gen1 = gen0; 
} 

PS. 범위 검사를 원할 때마다 v[i] 대신 v.at(i)을 사용하는 것이 좋습니다. 이것은 디버깅 문제에 상당한 도움이 될 수 있습니다.

+0

닫기 : 수동 할당 연산자를 삭제하고 컴파일러에서 처리하는 것을 잊었습니다. 제로 규칙! – Casey

+0

@Casey 꽤 맞습니다. 결정된. – sehe

+0

경이로운; 도와 주셔서 감사합니다. 나는 이것을 구현할 것이고 희망적으로 작동하도록 할 것이다. 추가 질문이 있으면 알려 드리겠습니다. – user2638374

관련 문제