2016-07-10 2 views
3

C에서 동적으로 크기가 지정된 배열이 필요한 게임을 만들려고하지만 동일한 코드가 다른 프로그램에서 작동하더라도 내 코드가 작동하지 않습니다. 여기C에서의 동적 메모리 할당이 작동하지 않습니다.

은 내 #includes

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "SwinGame.h" //API for graphics, physics etc 
#include <math.h> 
여기

있다 내 typedefs 사용 관련 structs

void add_enemy(enemy_data_array *enemies) 
{ 
    enemy_data *new_array; 
    enemies->size++; 
    new_array = (enemy_data *)realloc(enemies->data, sizeof(enemy_data) * enemies->size); 
    if (new_array) //if realloc fails (ie out of memory) it will return null 
    { 
    enemies->data = new_array; 
    // enemies->data[enemies->size - 1] = read_enemy_data(); 
    printf("Enemy added successfully!\n"); 
    } 
    else 
    { 
    printf("FAILED. Out of Memory!\n"); 
    enemies->size--; 
    } 
} 
: 여기
typedef struct position_data 
{ 
    double x; 
    double y; 
} position_data; 

typedef enum enemy_type_data {CIRCLE, TRIANGLE, SQUARE} enemy_type_data; 

typedef struct enemy_data 
{ 
    position_data location; 
    enemy_type_data type; 
    bitmap bmp; 
    double health; 
    double speed; 
    int path_to; 
} enemy_data; 

typedef struct enemy_data_array 
{ 
    int size; 
    enemy_data *data; 
} enemy_data_array; 

배열에 요소를 추가하는 기능이며

그리고 여기 내 함수 호출 및 변수 선언입니다. 메인 프로 시저의 내용 :

int main() 
{ 
    path_data my_path[41]; 
    enemy_data_array enemies; 
    enemies.size = 0; 
    add_enemy(&enemies); 
} 

왜 작동하지 않습니까?

+0

게시 된 코드에 '# include'문과 'bitmap'및 'position_data'정의와 같은 주요 세부 정보가 빠져 있습니다. 컴파일 할 때 항상 모든 경고를 활성화 한 다음 해당 경고를 수정하십시오. (최소한'gcc '의 경우'-Wall -Wextra -pedantic'도 사용합니다 :'-std = gnu99 -Wconversion') – user3629249

+0

은 이제 그 세부 사항을 추가하기 위해 편집 할 것입니다. Thanks @ user3629249 – Andrew

답변

6

자동 저장 기간이있는 초기화되지 않은 변수에 미정의 값 enemies->data을 전달하여 정의되지 않은 동작 을 호출했습니다(). add_enemy()을 사용하기 전에 초기화하십시오.

int main() 
{ 
    path_data my_path[41]; 
    enemy_data_array enemies; 
    enemies.size = 0; 
    enemies.data = 0; /* add this line */ 
    add_enemy(&enemies); 
} 

0널 포인터 상수하고 안전하게 NULL를 포인터로 변환 할 수 있습니다. NULL과 달리 0은 헤더를 포함하지 않고 작동합니다. 물론 적절한 헤더가 포함 된 enemies.data = NULL;을 사용할 수 있습니다.

+2

이 경우 최소한 하나의 멤버가 초기화되거나 할당 된 자동 구조체를 전달하는 것은 정의되지 않은 동작이 아닙니다. 불확정 값이있는 포인터에서 realloc이 호출되면 정의되지 않은 동작이 발생합니다. – 2501

3

@2501's explanation은 완전히 정확합니다. 또 다른 해결책은 다음과 같이 뭔가 add_enemy()의 구현을 변경하는 것입니다 :

void add_enemy(enemy_data_array *enemies) 
{ 
    enemy_data *new_array; 

    // check if size was non-zero 
    if (enemies->size++) 
    { 
    new_array = (enemy_data *)realloc(enemies->data, sizeof(enemy_data) * enemies->size); 
    } 
    // start new allocation 
    else 
    { 
    new_array = (enemy_data *)alloc(sizeof(enemy_data) * enemies->size); 
    } 

    if (new_array) //if (re)alloc fails (ie out of memory) it will return null 
    { 
    enemies->data = new_array; 
    // enemies->data[enemies->size - 1] = read_enemy_data(); 
    printf("Enemy added successfully!\n"); 
    } 
    else 
    { 
    printf("FAILED. Out of Memory!\n"); 
    enemies->size--; 
    } 
} 
2

당신이 "적"의 내용을 삭제하지 않았기 때문에 실패합니다. 이것은 스택 변수이기 때문에 스택에있는 모든 가비지 데이터를 포함합니다.

주 기능에서 enemies.data를 NULL로 설정하고 다시 시도하십시오.

관련 문제