2015-07-11 108 views
1

我有一種特殊結構的動態分配的載體,我想免費的,但軟件老是死機免費結構

結構是:

typedef struct { 
    Type_e type; 
    union { 
     char m_char; 
     int m_int; 
     // more types (non of them is a pointer) 
    } my_data; 
} Data_t; 

其中Type是一個枚舉包含所有可能的數據類型。

我分配和初始化向量如下

void vector(Data_t **vec, UInt32_t start_element, UInt32_t end_element, Type_e type) 
{ 
    UInt32_t i; 
    Data_t *vec_ptr; 

    *vec=(Data_t *)malloc((size_t) ((end_element-start_element+1) * sizeof(Data_t))); 

    vec_ptr = *vec; 

    if (!vec_ptr) 
    { 
     // Write error 
    } 

    for (i =start_element; i <= end_element + 1; i++) 
    { 
     vec_ptr->type = type; 
     switch (type) 
     { 
     case UINT32: vec_ptr->my_data.m_int = 0; break; 
     // more possible cases 
     default: 
      break; 
     } 
     (vec_ptr)++; 
    } 
} 

我調用該函數如下

Data_t *lVector = NULL; 
vector(&lVector,0,10,INT32) 

但是當我嘗試釋放分配的內存如下,

free (lVector+start_element-1); 
我試過
free (lVector+start_element); 

free (lVector); 

是START_ELEMENT = 0(在這種情況下)

但在所有情況下,它會崩潰。我做錯了什麼?

+0

標準警告:不要像'malloc'和朋友那樣強制轉換'void *'。 – Olaf

+0

給定分配'vec'的發佈方法,使用'free(vec);'釋放它。 (或者如果在調用者free'd,使用'免費(lvector);' – user3629249

回答

1

這個參數說指針數組爲類型「Data_t」

Data_t **vec, 

然而,這條線:

*vec=(Data_t *)malloc((size_t) ((end_element-start_element+1) * sizeof(Data_t))); 

分配內存的指針「Data_t」不是數組的數組爲' Data_t」

在C,不通過malloc

票面投返回值ameter對malloc()被自動一個 '爲size_t',因此投射到 '爲size_t' 只是雜波的代碼


這條線:

for (i =start_element; i <= end_element + 1; i++) 

迭代從索引爲0的數組索引11上但是,所述有效的索引是0至10爲C數組指數法從0開始,並在結束的sizeof(數組)-1


這一行:

(*vec)->type = type; 

預計'vec'實際上是指向struct的指針數組。但是,正如前面提到的,它不是


這一行:

*vec = *vec + sizeof(Data_t); 

通過結構但是陣列被適當步進,這失去的指針malloc分配存儲器,從而導致內存泄漏,因爲指針malloc分配存儲器丟失,從而不能被傳遞到自由()


這條線:

*vec = *vec - ((end_element-start_element+1) * sizeof(Data_t)); 

不太合適,因爲之前的'for'語句會迭代太多次。

強烈建議索引「vec」而不是更改vec內容。 I.E. vec [i]

+0

感謝有關鑄造到size_t的信息:) –

+0

遍歷數組,這個想法是針對任何大小從0到10的請求向量,將會有一個額外的1元素包含加密數據。所以我在malloc中分配內存時添加了一個額外的元素。是的,「<=」有錯誤,應該是「<」。刪除平等工作謝謝:) –

4

這是不正確的:

*vec = *vec + sizeof(Data_t); 

它前進*vecsizeof(Data_t)*sizeof(Data_t)字節,因爲指針算術由sizeof(*p)自動乘以積分常數。

替換爲(*vec)++,讓編譯器爲您做數學運算。同樣,在你操縱指針的所有地方刪除乘法。在你需要乘以sizeof的代碼中唯一的地方是當你撥打malloc時。

注意:您的代碼難以閱讀,因爲您在循環中前後移動。最好是聲明並使用一個普通的臨時指針來迭代向量,並且保持*vec固定爲由malloc分配的任何值。

+0

感謝您糾正這個錯誤,我認爲您的做法更具可讀性。請參閱我編輯的代碼。但是,這些更改不能修復問題是釋放分配的內存。你還有什麼我做錯了嗎? –

0

你在哪裏打電話free()

如果在vector()之內,您將免費'& lVector',它位於堆棧中,無法釋放。

您只能使用malloc()分配的空間,因此您可以免費獲得*vec,但不是vec。

+0

我想釋放調用函數中分配的內存,而不是在vector()函數內部。我嘗試免費(&lVector),但它是崩潰的:( –

3

您必須free確切的指針返回malloc,並且只做一次。您將返回值malloc存儲在*vec中,因此free(*vec)在調用函數中的相同函數或free(lVector)中將是正確的。但是,您隨後將其他值分配給*vec,因此爲了能夠free正確,您需要以某種方式恢復原始返回值malloc(更好的選擇幾乎可以肯定是使用另一個變量)。

你似乎也誤解了指針算術。 p += n已經推進了sizeof(*p) * n指向的地址。因此,您不得將*vec的更改乘以sizeof(Data_t)(即sizeof(**vec))。

+0

關於免費(vec),這是一個類型,我很抱歉這個類型,並且我在問題中糾正了它我應該是免費的(lVector) –

+0

For第二部分的評論,我重新做了代碼與@dasblinkenlight的意見,使正確的,但仍然崩潰時,我釋放分配的內存。我還缺少什麼嗎?或錯誤地編碼? –

+0

@ rasred2004只是爲了確保你是釋放原始指針,你如何從你的函數中完全刪除'vec'參數,而不是'Data_t * const vec = malloc(...)'並且有函數'return vec',調用者做'Data_t * const lVector = vector(0,10,INT32);'then later' free(lVector)' – Arkku