2016-03-21 178 views
1

我目前正試圖釋放分配的內存,但這樣做會導致程序崩潰。我對C和編程一般都很陌生,對於遇到問題以及由於缺乏經驗可能產生的任何其他問題,我將非常樂意。免費()函數導致程序崩潰

Pool* allocatePool(int x); 
void freePool(Pool* pool); 
void store(Pool* pool, int offset, int size, void *object); 

typedef struct _POOL 
{ 
    int size; 
    void* memory; 
} Pool; 

int main() 
{ 
    printf("enter the number of bytes you want to allocate//>\n"); 
    int x; 
    Pool* p; 
    scanf("%d", &x); 
    p=allocatePool(x); 
    freePool(p); 
    return 0; 
} 

/* Allocate a memory pool of size n bytes from system memory (i.e., via malloc()) and return a pointer to the filled data Pool structure */ 

Pool* allocatePool(int x) 
{ 
    static Pool p; 
    p.size = x; 

    p.memory = malloc(x); 
    printf("%p\n", &p); 

    return &p;//return the address of the Pool 
} 

/* Free a memory pool allocated through allocatePool(int) */ 
void freePool(Pool* pool) 
{ 
    free(pool); 
    printf("%p\n", &pool); 
} 
+4

您必須'free'您已經分配了相同的內存。你把'malloc'改爲'p.memory',但是你釋放了(&p)',它根本不是內存分配的堆,而是一個靜態對象的地址。 –

+0

它永遠不會是導致程序崩潰的'free()'函數。它是導致程序崩潰的代碼中的一個錯誤。 – SergeyA

+0

@SergeyA_Never_有點強。這有點像說你永遠不會被閃電擊中。確定它不太可能,但它不像malloc/free _somewhere_有任何錯誤的實現。 – Cubic

回答

3

您必須釋放您分配的相同內存。在這裏:

p.memory = malloc(x); 

你分配x字節p.memory。這意味着這裏:

free(pool); 
printf("%p\n", &pool); 

你應該釋放相同的內存。您嘗試free池對象,而不是在堆上分配。在你的實現中,它是一個持有單個池的靜態對象。嘗試free沒有在堆上分配的內存是未定義的行爲,在您的情況下崩潰。

上面的代碼還顯示了關於free的另一個誤解:它不會改變分配內存的句柄。它僅將先前分配的字節標記爲可再次使用。你的程序必須防止通過你有內存的指針訪問內存free d。

另外,&pool不是池對象的地址,而是本地指針變量的地址pool

要解決你的崩潰,改變你的函數:

void freePool(Pool *pool) 
{ 
    if (pool) free(pool->memory); 
} 
+0

仍然不會解決問題,因爲main中的p現在指向不再有效的內存。 – FredK

+0

@FredK錯誤,他將** static ** Pool的地址返回給main,並將它傳遞給freePool ...這裏沒有錯。 –

+0

啊 - 錯過了「靜態」聲明。仍然不是一個好的設計;如果第一次調用allocatePool()而沒有首先釋放p,內存,將會出現內存泄漏。 – FredK