2015-12-06 112 views
1

我想了解如何動態內存分配在C工作。所以我編碼:內存損壞導致免費()

typedef struct person{ 
    int id; 
    int credit; 
}person_t; 

typedef struct list{ 
    int id; 
    person_t * people; 
}list_t; 

int main(){ 
list_t * list; 
list = malloc(sizeof(list_t)); 
list->people = malloc(10 * sizeof(person_t)); //list for 10 people 

free(list->people); 
free(list); 
} 

,這似乎是正確的。然而,當我決定創建分配\釋放函數,雙免費或損壞錯誤開始出現:

void init_list(list_t * listptr, int size){ 
    listptr = malloc(sizeof(list_t)); 
    listptr->people = malloc(size * sizeof(person_t)); 
} 

void clear_list(list_t * listptr){ 
    free(listptr->people); 
    free(listptr); 
} 

int main(){ 
list_t list; 
init_list(&list, 10); //list for 10 people 
clear_list(&list); 
} 

輸出:

Error in ./list: double free or corruption (out) : 0x00007ffc1b3fba70 

爲什麼會是什麼?提前致謝。

+1

你正在通過值'listptr'到'init_list';它是該函數中的一個局部變量,並且在外部看不到它(即在'main'中)。所以你分配的內存實際上已經丟失了,然後你試圖釋放沒有'malloc'的內存,這是未定義的行爲。 – szczurcio

回答

1
void init_list(list_t * listptr, int size){ 
    listptr = malloc(sizeof(list_t)); 
    listptr->people = malloc(size * sizeof(person_t)); 
} 

是不正確的。您正在修改功能中的listptr。這不會改變mainlist的任何內容。您需要刪除該函數中更改listptr的行。用途:

// listptr is already a valid pointer. 
// There is no need to allocate memory for it. 
void init_list(list_t * listptr, int size){ 
    listptr->people = malloc(size * sizeof(person_t)); 
} 

你有clear_list一個糟糕的錯誤。

void clear_list(list_t * listptr){ 
    free(listptr->people); 
    free(listptr); 
} 

您對不是由呼叫分配給malloc指針調用freelistptr是指向在main中以堆棧創建的對象的指針。刪除第二個電話free。使用:

// listptr is a pointer to an object on the stack in main. 
// Trying to call free on it is an error. 
void clear_list(list_t * listptr){ 
    free(listptr->people); 
}