2017-02-15 7 views
0

어제 새 프로젝트 (roguelike)를 시작했습니다. 그것은 내 첫 번째, 그리고 나는 계속 같은 오류로 실행. 스크롤 맵을 구현하려고 시도한 후에 프로그램을 실행했지만 키를 누를 때마다 Visual Studio는 액세스 위반 읽기 위치가 있다는 메시지 상자를 표시합니다.C의 PDCurses (액세스 위반 읽기 위치 표시 유지)

#include "curses.h" 
#include <stdlib.h> 

#define MAX_HEIGHT 16 
#define MAX_WIDTH 21 

typedef struct tile 
{ 
    char *tile; 
    bool passable; 
}tile; 

typedef struct player 
{ 
    int xpos; 
    int ypos; 
    int dx; 
    int dy; 
}player; 

tile tileArray[] = { 
    {".",TRUE}, 
    {"#",FALSE}, 
    {"+",FALSE}, 
    {"/",TRUE} 
}; 

int mapArray[15][21] = { 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,1,1,1,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } 

}; 

typedef struct camPos 
{ 
    int y; 
    int x; 
}camPos; 

void initSetup(); 
player *actorSetup(); 
void refreshScreenMap(); 
void handleInput(); 
void drawScreenMap(); 
void interactionOpen(); 
bool isPassable(int y, int x); 
void startupScreen(); 

player *user; 
camPos cam; 

int main() 
{ 
    initSetup(); 

    user = actorSetup(); 
    cam.y = 2; 
    cam.x = 2; 

    startupScreen(); 

    while (TRUE) 
    { 
     drawScreenMap(); 
     refreshScreenMap(); 
     handleInput(); 
     clear(); 
    } 
    endwin(); 
    return 0; 
} 

void initSetup() 
{ 
    initscr(); 
    noecho(); 
    raw(); 
    keypad(stdscr,TRUE); 
} 

player *actorSetup() 
{ 
    player *newactor; 
    newactor = malloc(sizeof(player)); 
    newactor->xpos = 10; 
    newactor->ypos = 10; 
    return newactor; 
} 

void handleInput() 
{ 
    char button = getch(); 
    switch (button) 
    { 
     case 's': 
      user->dy++; 
      break; 
     case 'w': 
      user->dy--; 
      break; 
     case 'a': 
      user->dx--; 
      break; 
     case 'd': 
      user->dx++; 
      break; 
     case 'o': 
      interactionOpen(user); 
      break; 
    } 
    if (isPassable(user->ypos + user->dy, user->xpos + user->dx)) 
    { 
     user->ypos += user->dy; 
     user->xpos += user->dx; 
    } 
    else 
    { 
     user->dx = 0; 
     user->dy = 0; 
    } 
} 

void refreshScreenMap() 
{ 
    mvprintw(6, 8, "@"); 
    cam.x += user->dx; 
    cam.y += user->dy; 
} 

void drawScreenMap() 
{ 
    for (int y = 1; y < 12; y++) 
    { 
     move(y,1); 
     for (int x = 1; x < 16; x++) 
     { 
      mvprintw(y, x, tileArray[mapArray[cam.y + y][cam.x + x]].tile); 
     } 
    } 
} 

void interactionOpen() 
{ 
    if (mapArray[user->ypos + 1][user->xpos] == 2) 
    { 
     mapArray[user->ypos + 1][user->xpos] = 3; 
    } 
    else if (mapArray[user->ypos - 1][user->xpos] == 2) 
    { 
     mapArray[user->ypos - 1][user->xpos] = 3; 
    } 
    else if (mapArray[user->ypos][user->xpos + 1] == 2) 
    { 
     mapArray[user->ypos][user->xpos + 1] = 3; 
    } 
    else if (mapArray[user->ypos][user->xpos - 1] == 2) 
    { 
     mapArray[user->ypos][user->xpos - 1] = 3; 
    } 
    else if (mapArray[user->ypos + 1][user->xpos] == 3) 
    { 
     mapArray[user->ypos + 1][user->xpos] = 2; 
    } 
    else if (mapArray[user->ypos - 1][user->xpos] == 3) 
    { 
     mapArray[user->ypos - 1][user->xpos] = 2; 
    } 
    else if (mapArray[user->ypos][user->xpos + 1] == 3) 
    { 
     mapArray[user->ypos][user->xpos + 1] = 2; 
    } 
    else if (mapArray[user->ypos][user->xpos - 1] == 3) 
    { 
     mapArray[user->ypos][user->xpos - 1] = 2; 
    } 
} 

bool isPassable(int y, int x) 
{ 
    bool pass = tileArray[mapArray[y][x]].passable; 
    if (pass == FALSE) 
    { 
     return FALSE; 
    } 
    else if (y < cam.y || y >= (cam.y + 11)) 
    { 
     return FALSE; 
    } 
    else if (x < cam.x || x >= (cam.x + 15)) 
    { 
     return FALSE; 
    } 
    else 
    { 
     return TRUE; 
    } 
} 

void startupScreen() 
{ 
    mvprintw(10, 20, "________"); 
    mvprintw(11, 20, "\\______ \\ __ __ ____ ____ ____ ____ ____ "); 
    mvprintw(12, 20, " | | \\| | \\/ \\/___\\_/ __ \\/ _ \\/ \\ "); 
    mvprintw(13, 20, " | ` \\ |/ | \\/ /_/ > ___( <_>) | \\ "); 
    mvprintw(14, 20, "/_______ /____/|___| /\\___/\\___ >____/|___|/"); 
    mvprintw(15, 20, "  \\/   \\//_____/  \\/   \\/"); 
    mvprintw(16, 20, "Made by Will Reid"); 
    mvprintw(17, 20, "Press any key to start..."); 
    getch(); 
    clear(); 
} 
+1

* 정확히 * 충돌이 있습니까? 디버거를 사용하고 segfault를 일으키는 줄을 알려주십시오. –

+0

Game.exe의 0x00221CD5에서 처리되지 않은 예외가 발생했습니다. 0xC0000005 : 0xBEE161B4 위치를 읽는 액세스 위반입니다. (비주얼 스튜디오의 메시지) 라인은 bool pass = tileArray [mapArray [y] [x]]. passable; (isPassable 함수에서) 그러나, 패스를 TRUE로 변경하면 중단 점이 mvprintw (y, x, tileArray [mapArray [cam.y + y] [cam.x + x]]. tile);로 이동합니다. (drawScreenMap 함수에서). 그것을 살펴 주셔서 감사합니다! –

+1

그냥 추측 : 배열에 잘못된 인덱스를 사용하고있을 수 있습니다. int getMapValue (int x, int y);와 bool setMapValue (int x, int y, int value); 두 가지 함수를 만드는 것이 좋습니다. 'mapArray'에 접근 할 때마다이 함수들을 사용하십시오. 그런 다음 코드를 추가하여 인덱스가 범위 내에 있는지 확인할 수 있습니다. 일치하지 않으면 오류를 인쇄합니다. –

답변

0

문제는 isPassable에 사용 된 변수 cam가 초기화되지 않았 음이다

여기에 코드입니다.

==11010== 1 errors in context 1 of 7: 
==11010== Invalid read of size 8 
==11010== at 0x400B72: drawScreenMap (foo.c:151) 
==11010== by 0x40091E: main (foo.c:77) 
==11010== Address 0x58e8c2a0 is not stack'd, malloc'd or (recently) free'd 
==11010== 
==11010== 
==11010== 7 errors in context 2 of 7: 
==11010== Conditional jump or move depends on uninitialised value(s) 
==11010== at 0x40100E: isPassable (foo.c:203) 
==11010== by 0x400A46: handleInput (foo.c:124) 
==11010== by 0x400928: main (foo.c:79) 
==11010== Uninitialised value was created by a heap allocation 
==11010== at 0x4C28BED: malloc (vg_replace_malloc.c:263) 
==11010== by 0x400974: actorSetup (foo.c:97) 
==11010== by 0x4008F9: main (foo.c:69) 

는 또한, 컴파일러 경고 켜면 (비주얼 스튜디오는 ... 컴파일러 경고가) 몇 가지 문제를 보여 주었다 :

나는 이것을보고 (리눅스) Valgrind의 사용.