2010-07-02 30 views
9

Có bất kỳ đảm bảo nào rằng realloc() sẽ luôn thu nhỏ bộ đệm tại chỗ không ?? Vì vậy mà sau:Realloc có được đảm bảo ở đúng vị trí khi bộ đệm bị co lại không?

new_ptr = (data_type *) realloc(old_ptr, new_size * sizeof(data_type)); 

sẽ luôn luôn cung cấp cho new_ptr == old_ptr nếu new_size < old_size (tất nhiên trừ khi new_size == 0). Nó có vẻ hợp lý (với tôi) rằng nó sẽ hoạt động theo cách này, nhưng tò mò liệu tiêu chuẩn có thực thi nó hay không.

Tôi nhìn vào việc tái phân bổ mảng of-phi POD kiểu dữ liệu, và nếu hành vi trên được đảm bảo đã suy nghĩ rằng chiến lược sau đây ít nhất có thể cho phép hiệu quả "thu hẹp":

if (new_size > old_size) 
{ 
    // malloc() a new buffer 
    // use placement copy constructor to copy old objects over 
    // free() old buffer 
} 
else 
if (new_size < old_size) 
{ 
    // explicit destruction of unneeded objects 
    // realloc() buffer 
} 

tôi "m mong rằng một" co lại "tại chỗ sẽ mạnh mẽ ngay cả khi loại dữ liệu có tham chiếu/con trỏ tự hoặc bất cứ điều gì ...

+0

Cảm ơn mọi người đã bình luận. Tôi đoán tôi chỉ tìm thấy nó khá lãng phí và không hiệu quả để phải phân bổ một bộ đệm mới và làm một bản sao đầy đủ để đạt được một "thu nhỏ" ... –

+0

Sẽ không thêm vào điệp khúc của "không" ở đây, bạn sẽ nhận được ý tưởng của bây giờ. Nhưng một tác dụng phụ không mong muốn của việc đảm bảo rằng khối được phân bổ lại sử dụng lại cùng một bộ nhớ khi thu nhỏ là bạn không thể sử dụng [đối tượng phân bổ nhỏ] (http://www.developer.com/ws/brew/article.php/3315011 /Small-Memory-Allocation.htm) bên trong malloc/realloc, vì các trình phân bổ này nhóm các đối tượng có kích thước bằng nhau với nhau. –

+0

Lý do khác bạn không thể mong đợi realloc luôn sử dụng lại cùng một bộ nhớ là hầu hết các mục đích chung đặt thông tin quản lý (kích thước khối, con trỏ tới khối tiếp theo trong heap) trong tiêu đề bên phải "ở phía trước" của bộ nhớ được cấp phát. Vì vậy, nếu bạn có một khối đang ngồi giữa hai khối được phân bổ và được phân bổ lại thành một từ nhỏ hơn, sẽ không có chỗ để đặt tiêu đề cho từ bộ nhớ giải phóng, làm mất hiệu quả và phân mảnh vĩnh viễn đống của bạn. –

Trả lời

7

No.

Vậy đó. Không có điều này "nó có thể làm việc trong một số kiến ​​trúc" hoặc "nó nên, dựa trên kinh nghiệm". Tiêu chuẩn nêu rõ rằng địa chỉ có thể thay đổi, do đó, hãy dựa vào rằng và không có gì khác.

Về mặt mã hóa theo tiêu chuẩn: làm hoặc không. Không có "thử" :-)


Từ c99:

Hàm realloc deallocates đối tượng cũ được trỏ đến bởi ptr và trả về một con trỏ đến một đối tượng mới có kích thước theo quy định của kích thước. Nội dung của đối tượng mới phải giống với nội dung của đối tượng cũ trước khi deallocation, lên đến kích thước mới và cũ hơn. Bất kỳ byte nào trong đối tượng mới vượt quá kích thước của đối tượng cũ đều có giá trị không xác định.

Nếu ptr là một con trỏ rỗng, hàm realloc hoạt động giống như hàm malloc cho kích thước được chỉ định.Nếu không, nếu ptr không khớp với một con trỏ trước đó được trả về bởi hàm calloc, malloc hoặc realloc, hoặc nếu không gian đã được deallocated bởi một cuộc gọi đến hàm free hoặc realloc, hành vi này là không xác định. Nếu bộ nhớ cho đối tượng mới không thể được cấp phát, đối tượng cũ không được deallocated và giá trị của nó không thay đổi.

Hàm realloc trả về một con trỏ đến đối tượng mới (thể có cùng một giá trị như một con trỏ đến đối tượng cũ), hoặc một con trỏ null nếu đối tượng mới không thể phân bổ.

0

Không, không có sự bảo đảm như vậy. nơi, nhưng họ không bị ràng buộc để làm như vậy.

2

Nói chung nó có, nhưng nó không phải là garanted (tất cả phụ thuộc vào kiến ​​trúc của bạn). Vì vậy, Bạn không nên dựa vào nó trên hành vi như vậy

EDIT:

tham khảo: http://opengroup.org/onlinepubs/007908775/xsh/realloc.html

Sau khi hoàn thành công với một kích thước không bằng 0, realloc() trả về một con trỏ đến (có thể di chuyển) không gian được phân bổ.

1

Một số nhà phân phối sử dụng chiến lược "xô", trong đó phân bổ có kích thước từ, 2^3 đến 2^4, chuyển đến cùng một nhóm phân bổ. Điều này có xu hướng ngăn chặn các trường hợp cực kỳ phân mảnh bộ nhớ mà nhiều phân bổ nhỏ trải rộng trên heap ngăn chặn phân bổ lớn từ thành công. Rõ ràng, trong trình quản lý heap như vậy, việc giảm kích thước của một phân bổ có thể ép nó vào một nhóm khác.

5

No. Bạn sẽ không dựa vào điều này.

Theo spec 7.20.3.4/4:

Chức năng realloc trả về một con trỏ đến đối tượng mới (thể có giá trị giống như một con trỏ đến đối tượng cũ ), hoặc một con trỏ rỗng nếu đối tượng mới không thể được phân bổ .

+3

+1 cho mục đích. :-D –

+0

+1 Owen cho thông tin chi tiết (: – Poni

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