2013-05-21 8 views
15

Có hai cách để cấp phát bộ nhớ cho một mảng, trong đó kích thước không được biết lúc đầu. Cách phổ biến nhất là sử dụng malloc như thế nàymảng malloced VS. variable-length-array

int * array; 
... // when we know the size 
array = malloc(size*sizeof(int)); 

Nhưng đó là hợp lệ quá trong C99 để xác định các mảng sau khi chúng tôi biết kích thước.

... // when we know the size 
int array[size]; 

Có phải họ hoàn toàn không?

+4

Thứ hai, ngay cả trong C99, không phải lúc nào cũng hợp lệ. Theo C99 §6.10.8.3 Macro tính năng có điều kiện, việc triển khai có thể xác định ** __ STDC_NO_VLA __ ** và *** không *** thực hiện các mảng độ dài biến, và * vẫn tuân thủ tiêu chuẩn. * – WhozCraig

+2

** Đây không phải là câu hỏi trùng lặp **! Không có câu hỏi nào trong số các câu hỏi được tham chiếu có chi tiết về sự khác biệt. – Jens

+2

@WhozCraig AFAIK, đó là một điều 2011. Không có phần như vậy trong những gì tôi có mà purports là một bản sao của tiêu chuẩn C99. –

Trả lời

26

Không, chúng không hoàn toàn giống nhau. Trong khi cả hai cho phép bạn lưu trữ cùng một số và loại đối tượng, ghi nhớ rằng:

  • Bạn có thể free() một mảng malloced, nhưng bạn có thể không free() một mảng chiều dài thay đổi (mặc dù nó đi ra khỏi phạm vi và chấm dứt để tồn tại khi khối kèm theo bị bỏ lại). Trong thuật ngữ kỹ thuật, chúng có thời lượng lưu trữ khác nhau : được phân bổ cho malloc so với tự động cho các mảng độ dài thay đổi.
  • Mặc dù C không có khái niệm về một chồng, nhiều thực hiện phân bổ một mảng chiều dài thay đổi từ chồng, trong khi malloc phân bổ từ đống. Đây là sự cố trên các hệ thống có giới hạn ngăn xếp, ví dụ: nhiều hệ điều hành nhúng, trong đó kích thước ngăn xếp là theo thứ tự của kB, trong khi đống lớn hơn nhiều.
  • Nó cũng dễ dàng hơn để kiểm tra cho một phân bổ không thành công với malloc hơn với một mảng chiều dài biến.
  • bộ nhớ malloced có thể được thay đổi kích thước với realloc(), trong khi VLAs không thể (chính xác hơn chỉ bằng cách thực hiện lại khối với thứ nguyên mảng khác - làm mất nội dung trước đó).
  • Việc triển khai C89 được lưu trữ chỉ hỗ trợ malloc().
  • Việc triển khai C11 được lưu trữ có thể không hỗ trợ các mảng độ dài biến đổi (sau đó phải xác định __STDC_NO_VLA__ làm số nguyên 1 theo C11 6.10.8.3).
  • Mọi thứ khác tôi đã bỏ lỡ :-)
+2

Một VLA nằm ngoài phạm vi (ngừng hiển thị) ở cuối khối bao quanh bởi vì nó có phạm vi khối.Nó ngừng tồn tại ở cuối khối vì nó có thời lượng lưu trữ tự động. Hai thứ khác nhau. –

+0

@KeithThompson Cảm ơn gợi ý thuật ngữ; Tôi đã chỉnh sửa câu trả lời để chính xác hơn. – Jens

+2

@KeithThompson: Để chính xác, số nhận dạng của mảng nằm ngoài phạm vi của các khối bao quanh. Phạm vi là thuộc tính của số nhận dạng (tên), không phải của đối tượng. Một đối tượng có thể được truy cập bên ngoài phạm vi của mã định danh của nó, như khi địa chỉ của nó được chuyển đến một thường trình khác. –