2014-07-07 2 views
0

저는 SDL을 사용하여 그래픽 게임을 작성하는 초보 프로그래머입니다. 타일 ​​시트를 섹션 또는 "클립"으로 분할하여 배열에 넣는 기능과 특정 "클립"을 화면에 그려주는 기능이 의도 한대로 작동하지 않습니다.C++ 포인터 매개 변수 문제

void split_tilesheet(int width, int height, int space, Entity * ent){ 
    std::cout << "Splitting Tileset..."; 

    int t_width = (width/SPR_W); 
    int t_height = (height/SPR_H); 
    int numTiles = (t_width * t_height); 

    ent = new Entity [numTiles + 1]; 
    if(ent == NULL){ 
     err("!failed to alloc!"); 
    }else{ 
     std::cout << "allocated"<< std::endl; 
    } 
    int count = 0; 
    for(int i = 0; i < t_width; i++){ 
     for(int j = 0; j < t_height; j++){ 

      ent[count].bounds.x = i * SPR_W; 
      ent[count].bounds.y = j * SPR_H; 
      ent[count].bounds.w = SPR_W; 
      ent[count].bounds.h = SPR_H; 
      ent[count].id = ent[i].x + (ent[i].y * t_width); 
      count++; 
     } 
    } 
} 

void draw_room(char tiledata[MAP_MAX_X][MAP_MAX_Y], Entity * ent){ 
SDL_Rect bounds; 
    for(int x = 0; x < MAP_MAX_X; x++){ 
     for(int y = 0; y < MAP_MAX_Y; y++){ 

      if(tiledata[x][y] == '0' || tiledata[x][y] == ' ' || tiledata[x][y] == '\n'){ 
       draw_img(x * SPR_W , y * SPR_H, tiles, bounds, ent[0].bounds); 
      } 
      if(tiledata[x][y] == '1'){ 
       draw_img(x * SPR_W , y * SPR_H, tiles, bounds, ent[1].bounds); 
      } 
     }   
    } 
} 

class Entity 
{ 
public: 
    SDL_Rect bounds; 
    SDL_Surface* sprite; 
    int id; 
    int x; 
    int y; 
    int w, h; 
}; 

런타임시 메모리를 동적으로 할당하기 위해 포인터를 사용하려고했습니다. 프로그램이 컴파일되지만 segfaults입니다. gdb는 segfault가 draw_room() 함수로 인해 발생한다고 말하지만 그 이유는 알 수 없습니다. 나는 draw_room 함수에 전달 된 포인터가 있었다 :

Entity * floor0_clips = NULL; 

이 ...

Entity * floor0_clips; 

이 도와주세요 중 하나가 작동하지 않았다

+0

해당 함수를 호출 할 때마다 메모리가 누수됩니다. 그리고'new'는 실패 할 때 예외를 던집니다. 그래서 널 포인터를 검사하는 것이 중복됩니다. – chris

+0

그래서 메모리 누출 문제를 해결할 수 있을까요? 함수의 끝에 delete [] ent를 추가 하시겠습니까? – glycerinlaminate

+0

자신을 관리해야하는 것이 아니라 벡터를 사용하십시오. 그리고 호출자에게'ent '에 대한 변경 사항을 전파하려는 경우 참조를 사용하십시오. – chris

답변

2

C++ 사용 패스에 의해 값 (당신이하지 않는 한 당신이하지 않은 참조로 패스를 지정하십시오).

함수의 변수는 주어진 인수의 복사본입니다. 예를 들어 :

int func(int x) 
{ 
    x = 5; 
} 

int main() 
{ 
    int y = 6; 
    func(y); 
    // here, `y` is still `6` 
} 

귀하의 경우는 근본적으로이 동일합니다. 함수에 floor0_clips을 보내면 함수는 원본을 변경하지 않고 복사본을 업데이트합니다.

대신 전달 기준을 사용하려면 변수 이름 바로 앞에 & 기호를 넣으십시오 (예 : Entity * &ent). 함수를 호출하는 코드에서 아무 것도 변경하지 마십시오. 값이 값으로 전달되는지 아니면 참조로 전달되는지를 결정하는 것은 함수의 매개 변수 목록 선언입니다.

NB. 어쨌든 너무 많은 엔티티를 할당하는 것 같습니다 (이유는 + 1?).

+0

감사합니다. 지금 일합니다. – glycerinlaminate