2014-11-15 2 views
0
#include<stdio.h> 
#include<stdlib.h> 
#include<stdbool.h> 
#include<string.h> 

struct date { 
    int year; 
    int month; 
    int day; 
}; 

struct person{ 
    char name[64]; 
    struct date birthday; 
}; 

struct aop { 
    int max; 
    struct person **data; 
}; 

struct aop *create_aop(int max) { 
    struct aop *new = malloc(sizeof(struct aop)); 
    new->data = malloc(max*sizeof(struct person)); 
    for (int i=0; i<max; i++) { 
    new->data[i] = NULL; 
    } 
    new->max = max; 
    return new;} 

void destroy_aop(struct aop *a) { 
    free(a->data); 
    free(a); 
} 


int add_person(struct aop *a, char *name, struct date birthday) { 
    if (a->data[a->max-1] != NULL) { 
     return -1; 
    } 
    struct person *new_person = malloc(sizeof(struct person)); 
    strcpy(new_person->name, name); 
    new_person->birthday = birthday; 
    for (int i=0; i<a->max; i++) { 
     if (a->data[i] == NULL) { 
      a->data[i] = new_person; 
      break; 
     } 
    } 
    free(new_person); 
    return 0; 
}  

내가 작성한 코드에 대해 몇 가지 질문이 있습니다. 첫째, 사람의 이름과 생일을 초기화하기 위해 create_aop에 추가 코드를 추가해야합니까? 그리고 add_person의 free (new_person) 이후에 a-> data [0] -> name에 도달 할 수 없다는 것을 알았습니다. 다른 포인터를 사용하지 않고 a-> data [i]를 어떻게 바꿀 수 있습니까?포인터에 메모리를 할당하는 방법

struct aop *birthdays(const struct aop *a, int month) { 
    int m = a->max; 
    struct aop *n = create_aop(m); 
    int j = 0; 
    for (int i=0; i<m; i++) { 
     if (a->data[i] != NULL) { 
      if (a->data[i]->birthday.month == month) { 
       n->data[j] = a->data[i]; 
       j++; 
      } 
     } else { 
      break; 
     } 
    } 
    if (j == 0) { 
     return NULL; 
    } 
    return n; 
} 

위의 기능을 실행할 때마다 메모리에 오류가 있습니다. 나는 몇 시간 동안 그것에 대해 생각 해왔다.하지만 이것에 무엇이 잘못되었는지 전혀 모른다.

+1

'새로 만들기 -> 데이터 = malloc에 ​​(최대 *의를 sizeof (구조체 사람));'->'새로 만들기 -> 데이터 =은 calloc (최대,를 sizeof (구조체 사람 *)),'free (new_person);' – BLUEPIXY

+1

'sizeof (struct person *)'보다'sizeof * new-> data'가 더 좋습니다. 오류가 발생하기 쉽습니다. – Deduplicator

+0

일반적으로 'new'는 예약어입니다. 더 나은 이름을 사용하도록 제안하십시오. – user3629249

답변

1

이 코드에는 두 가지 큰 실수가 있습니다. 첫째, struct aop에서 데이터 배열의 할당에 결함이 있습니다.

new->data = malloc(max*sizeof(struct person)); 

구조체의 최대 길이의 메모리 구조를 가리 키지 않으시겠습니까? 이 포인터에 대한 포인터이기 때문에, 즉

new->data = malloc(max*sizeof(struct person*)); 

또한 데이터가 직접 사람을 구조체를 가리 할 수있는, 크기는 포인터의 최대 시간 길이이어야합니다. 그러면 첫 번째 줄은 정확할 것이며 새 사람을 만들 때마다 메모리를 할당 할 필요가 없습니다. 대신 데이터가 가리키는 메모리를 사용하면됩니다.

등등.

둘째, 생성 직후에 구조체를 해제하는 것입니다. 어드레스는 (그것이 더 이상 malloc에 ​​의해 잠겨 아니기 때문에) 언제든지 덮어 쓸 수 가리키는 때문에

free(new_person); 

지금 aop-는> 데이터 [I]를 매다는 포인터이다. 대신 파괴 기능에서 해제해야합니다. 그것은 다음과 같이 보일 수 있습니다

void destroy_aop(struct aop *a) {  
    int i; 
    for(i = 0; i < a->max; i++) 
    { 
     if(a->data[i] != NULL) { 
     free(a->data[i]); 
     } 
    } 
    free(a->data); 
    free(a); 
} 
+0

이 문제가 해결 된 것 같습니다. 여기에 또 다른 질문이 있습니다. 이중 자유 란 무엇입니까? 내 주요 기능을 실행 하고이 오류가 발생합니다. –

+1

이것은 코드 어딘가에 이전에 free()라고 부른 포인터를 해제한다는 것을 의미합니다. 예를 들어, 당신이 add_person 함수에서 free()를 호출 한 채 남겨두고 destroy 함수를 복사했다면, 파괴 할 때 두 배의 free를 얻을 수 있습니다. –

+0

좋아,하지만 난 내 코드에서 한 번 이상 포인터를 무료로 생각하지 않지만 오류가 두 번 무료 시도하고있다. 다른 메모리 오류가 발생했기 때문입니까? 내 생일 코드 기능을 위해 뭔가 잘못되었거나이를 고칠 방법이 있습니까? –

관련 문제