2010-10-08 46 views
6

Tôi không hiểu tại sao, trong mã này, cuộc gọi đến "tự do" gây ra một lỗi segmentation:Malloc, miễn phí và phân đoạn lỗi

#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; 
} 

Ai đó có thể giải thích cho tôi?

Cảm ơn, Segolas

+0

Cũng có một cái nhìn tại http://www.hpl.hp.com/personal/Hans_Boehm/gc/ nó thực sự tốt đẹp. –

Trả lời

14

Bạn đang phân bổ bộ nhớ sử dụng malloc một cách chính xác:

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

sau đó bạn làm điều này:

arr = "xxxxxxx"; 

điều này sẽ gây arr trỏ đến địa chỉ của chuỗi chữ "xxxxxxx", rò rỉmalloc bộ nhớ đã chỉnh sửa của bạn. Và cũng gọi số free trên địa chỉ của chuỗi ký tự dẫn đến hành vi không xác định.

Nếu bạn muốn sao chép chuỗi vào phân bổ sử dụng bộ nhớ strcpy như:

strcpy(arr,"xxxxxxx"); 
+1

Bạn đang ở trên phần UB: Gọi 'miễn phí' với bất kỳ giá trị con trỏ nào (ngoài' NULL') không phải từ 'malloc' hoặc' realloc' cho hành vi không xác định. – schot

2

Dòng thứ ba của char_arr_allocator() làm mờ nhạt những malloc() kết quả của bạn và thay thế nó bằng một đoạn bộ nhớ tĩnh trong trang dữ liệu. Gọi số free() để làm điều này.

Sử dụng str[n]cpy() để sao chép chuỗi ký tự vào bộ đệm thay thế.

2

Khi bạn viết một chuỗi không đổi trong C, chẳng hạn như "xxxxxx", điều xảy ra là chuỗi đó đi trực tiếp vào tệp thực thi. Khi bạn đề cập đến nó trong nguồn của bạn, nó được thay thế bằng một con trỏ đến bộ nhớ đó. Vì vậy, bạn có thể đọc các dòng

arr = "xxxxxxx"; 

Xử arr như một số như một cái gì đó như:

arr = 12345678; 

đâu con số đó là một địa chỉ. malloc đã trả về một địa chỉ khác, và bạn đã ném nó đi khi bạn gán một địa chỉ mới cho arr. Bạn đang nhận được một segfault bởi vì bạn đang cố gắng để giải phóng một chuỗi liên tục mà là trực tiếp trong thực thi của bạn - bạn không bao giờ được phân bổ nó.

0

Bạn đang đặt arr thành giá trị trả lại là malloc(), điều này là chính xác. Nhưng sau đó bạn chỉ định lại nó để trỏ vào hằng số chuỗi "xxxxxxx". Vì vậy, khi bạn gọi free(), bạn đang yêu cầu thời gian chạy để giải phóng chuỗi không đổi, gây ra lỗi seg.

Các vấn đề liên quan