2010-10-08 82 views
6

我不明白,爲什麼在這段代碼,調用「自由」導致段錯誤:malloc的,免費的,分段錯誤

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

char *char_arr_allocator(int length); 

int main(int argc, char* argv[0]){ 

    char* stringa = NULL; 
    stringa = char_arr_allocator(100); 
    printf("stringa address: %p\n", stringa); // same address as "arr" 
    printf("stringa: %s\n",stringa); 
    //free(stringa); 

    return 0; 
} 

char *char_arr_allocator(int length) { 
    char *arr; 
    arr = malloc(length*sizeof(char)); 
    arr = "xxxxxxx"; 
    printf("arr address: %p\n", arr); // same address as "stringa" 
    return arr; 
} 

有人能解釋一下?

感謝, Segolas

+0

也看看http://www.hpl.hp.com/personal/Hans_Boehm/gc/這太好了。 – 2010-10-08 12:21:27

回答

14

您正在使用malloc正確地分配內存

arr = "xxxxxxx"; 

這將導致arr指向字符串字面"xxxxxxx"的地址,泄漏您的malloc ed內存。並且在字符串文字的地址上調用free會導致未定義的行爲。

如果你想副本串入分配的內存使用strcpy爲:

strcpy(arr,"xxxxxxx"); 
+1

你對UB部分是正確的:使用任何指針值(不是'NULL')而不是'malloc'或'realloc'調用'free'會導致未定義的行爲。 – schot 2010-10-08 11:10:12

2

char_arr_allocator()第三行抹了你的malloc()結果並與靜態存儲器中的數據頁塊替換它。打這個電話free()

使用str[n]cpy()將字符串文字複製到緩衝區。

2

當您在C中編寫常量字符串(如"xxxxxx")時,會發生什麼情況是該字符串直接進入可執行文件。當您在源代碼中引用它時,它會被指向該內存的指針替換。所以,你可以讀取行

arr = "xxxxxxx"; 

治療arr爲數字,就像這樣:

arr = 12345678; 

如果這個數字是一個地址。 malloc已經返回了一個不同的地址,並且當您將一個新地址分配給arr時,您將其扔掉了。您正在獲取段錯誤,因爲您試圖釋放一個直接位於可執行文件中的常量字符串 - 您從未分配過它。

0

您正在將arr設置爲返回值malloc(),這是正確的。但是,您隨後將其重新指定爲指向字符串常量"xxxxxxx"。所以當你打電話給free()時,你要求運行時釋放一個字符串常量,這會導致seg故障。

arr = malloc(length*sizeof(char)); 

那麼你這樣做::