2012-04-08 36 views
5

Nếu tôi sẽ viết:chuỗi Giải phóng trong C

char *a=malloc(sizeof(char)*4); 
a="abc"; 
char *b="abc"; 

sao tôi cần phải giải phóng bộ nhớ này, hoặc là nó được thực hiện bởi hệ thống của tôi?

+0

Một nhận xét bổ sung là tôi tin rằng bạn không cần sizeof (char) vì trong tất cả các triển khai tôi đã thấy cho đến nay luôn luôn là 1 byte. Vì vậy, malloc (4); sẽ đủ – Lefteris

+1

@Lefteris thực sự thực hiện ở trên là tốt. Mặc dù hầu hết các hệ thống sử dụng một ký tự byte, việc thực hiện ở trên lá nó rõ ràng những gì đang được phân bổ, và nếu mã được thay đổi để sử dụng unichars, mà thường là hai byte, sau đó nó sẽ được dễ dàng hơn để thay đổi. – ThomasW

+0

@ThomasW Tôi sợ tôi không chắc chắn chính xác một unichar là gì nhưng tôi cho rằng nó phải làm với unicode. Tìm kiếm nhanh trên google gợi ý mục tiêu-c là ngôn ngữ khác: P Nhưng mọi ký tự unicode thường không được gọi là char. Lấy các ký tự rộng wchar_t chẳng hạn. Có thể là sai mặc dù, nhưng đây là những gì tôi đã thấy cho đến nay với việc triển khai tôi đã xử lý với – Lefteris

Trả lời

10

Trong trường hợp của bạn, bạn sẽ không có bất kỳ cách nào để giải phóng bộ nhớ được cấp phát động vì bạn đang mất tham chiếu đến nó.

Hãy thử điều này:

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

int main() 
{ 
    char *a=(char*)malloc(sizeof(char)*4); 
    printf("Before: %p\n",a); 
    a = "abc"; 
    printf("After: %p\n",a); 
    free(a); 
    char *b = "abc"; 

    return 0; 
} 

Bạn sẽ có được

Before: 0x100100080 
After: 0x100000f50 

Bạn sẽ thấy rằng hai con trỏ khác nhau.Điều này bởi vì các chuỗi chữ "abc" được đặt vào khu vực dữ liệu của các tập tin nhị phân và khi bạn làm

a = "abc" 

bạn đang thay đổi con trỏ của a để trỏ đến chuỗi đen liên tục "abc" và bạn đang mất đi ký ức được phân bổ trước đó. Gọi free trên a không chính xác nữa, chỉ vì nó sẽ không trỏ đến địa chỉ được cấp phát động hợp lệ nữa. Để bảo tồn con trỏ và có thể giải phóng nó, bạn nên sao chép chuỗi bằng

strncpy(a, "abc", 4) 

Điều này sẽ sao chép các ký tự từ chữ sang phương pháp được phân bổ động, giữ nguyên con trỏ ban đầu.

+2

strcpy là gốc của nhiều tràn bộ đệm. Sử dụng strncpy thay thế. – rampion

+0

Bạn nói đúng, tôi chỉ đang xem xét trường hợp cụ thể này, hãy để tôi chỉnh sửa nó – Jack

+0

@rampion Chỉ vì tò mò tại sao bạn lại nói điều này? Bởi vì các bản sao strcpy strlen (nguồn) byte có thể không phải lúc nào cũng được kiểm tra so với kích thước bộ đệm của đích? Hay tôi hiểu sai? – Lefteris

0

có, bạn cần giải phóng bộ nhớ được trả lại bởi malloc.

3

Bạn không thể gán chuỗi theo cách này với C

a = "abc" 

Tuy nhiên nếu bạn sử dụng malloc sau đó bạn phải sử dụng free, như thế này

free(a); 

Nhưng chú ý nếu bạn sử dụng free(a) tại của bạn ví dụ bạn gặp lỗi. Bởi vì sau malloc bạn thay đổi giá trị con trỏ a thành chuỗi tĩnh "abc"; Vì vậy, free(a) tiếp theo cố gắng giải phóng dữ liệu tĩnh. Và bạn nhận được lỗi.

4

Bạn đã bị rò rỉ bộ nhớ ở đây. Khi bạn đặt a="abc", bạn không làm đầy bộ nhớ bạn vừa cấp phát, bạn chỉ định lại con trỏ để trỏ đến chuỗi tĩnh "abc". b trỏ đến cùng một chuỗi tĩnh.

Điều bạn muốn thay thế là strncpy(a, "abc", 4), sẽ sao chép nội dung của "abc" vào bộ nhớ bạn đã phân bổ (trong đó a điểm đến).

Sau đó, bạn sẽ cần giải phóng khi hoàn tất.

2

Câu trả lời đơn giản có, không. Ngoài ra mã của bạn là lỗi.

câu trả lời cụ thể:

char *a=malloc(sizeof(char)*4); 

Bạn phân bổ bộ nhớ, do đó bạn nên giải phóng nó.

a="abc"; 

này gán một con trỏ đến một chuỗi liên tục để char* a bạn, bằng cách làm như vậy bạn mất con trỏ vào bộ nhớ được phân bổ trong dòng đầu tiên, bạn nên hằng xâu bao giờ miễn phí.

Sử dụng strcpy(a,"abc"); thay vì a="abc"; để di chuyển chuỗi vào bộ nhớ được cấp phát của bạn.

+2

strcpy là gốc của nhiều tràn bộ đệm. Sử dụng strncpy thay thế. – rampion

0

Có, nó sẽ gây ra rò rỉ bộ nhớ. Hệ thống không thể xử lý vụ việc.

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