2012-11-09 21 views
9

Nếu tôi làm điều này: -do std :: function and std :: bind thực hiện phân bổ bộ nhớ động?

class Thing 
{ 
    ... 
    void function (const std::string& message); 
}; 

std::list<std::function<void()>> work; 

và trong một số thành viên của "Thing"

work.push_back(std::bind(&Thing::function, this, "Hello")); 

Có hai cuộc gọi đến std :: ràng buộc hoặc việc sử dụng std :: chức năng <> nguyên nhân bất kỳ phân bổ bộ nhớ động nào bằng cách sử dụng mới hay cách khác? Hoặc là tất cả lưu trữ được phân bổ vào thời gian biên dịch? Nếu tiêu chuẩn không nói bất cứ điều gì, những gì về trong visual studio 2012 như chương trình của tôi sẽ chỉ cần xây dựng trên đó, và hiệu quả tôi có lẽ cần phải tránh phân bổ bộ nhớ động ở nơi tôi đang nghĩ đến việc sử dụng cơ chế này.

+6

"vì hiệu quả Tôi có thể" Bạn không nên giả định về hiệu quả như vậy. – slaphappy

+5

Sử dụng 'std :: list' sẽ gây ra cấp phát bộ nhớ mỗi khi bạn thêm một mục vào danh sách. –

+1

Ahahahahahaha tránh phân bổ động trong khi sử dụng std :: list –

Trả lời

14

Các tiêu chuẩn không xác định, nhưng nhìn chung nó rất dễ dàng để thấy rằng std::function phải cấp phát bộ nhớ ít nhất là trong một số trường hợp:

struct huge { char c[10000]; }; 
void foo(const huge &); 
std::function<void()>{std::bind(foo, huge{})}; 

Mặt khác, nó có thể cho nó để tránh phân bổ trong ít nhất một số trường hợp bằng cách chọn đối tượng hàm của nó bên trong một bộ đệm preallocated bên trong dấu chân của đối tượng function; rõ ràng là có một sự cân bằng vì điều này có thể làm cho các ứng dụng khác chiếm nhiều bộ nhớ hơn. Việc triển khai tốt sẽ có thể tránh phân bổ bộ nhớ khi lưu trữ một con trỏ hàm thô trong đối tượng function và có thể cũng cho một số mem_fn, nhưng ít khả năng nó sẽ làm như vậy cho một bind.

Ví dụ: con trỏ đối tượng, con trỏ hàm và con trỏ hàm của thành phần libstdC++ (g ++), cũng như bất kỳ thứ gì khác phù hợp với cùng một dấu chân, ví dụ: các functors không quốc tịch (union _Nocopy_types).

Nếu bạn có thể, bằng cách đảo ngược dòng điều khiển của bạn để chấp nhận đối tượng functor templated thay vì function bạn có thể tránh bất kỳ cấp phát bộ nhớ thêm:

template<typename F> 
void my_algorithm(const F &); 
my_algorithm(std::bind(foo, huge{})); 
+0

Ok có ý nghĩa, cảm ơn bạn – jcoder

0

Tôi không chắc chắn về điều này. Tôi đoán, như ecatmur cho thấy, nó phụ thuộc vào việc thực hiện std cho nền tảng đó. Đối với các vấn đề tương tự, tôi đã thành công tốt bằng cách sử dụng triển khai này từ dự án mã. Nó hỗ trợ một số lượng tốt các nền tảng. Rất tốt tài liệu và không có phân bổ bộ nhớ động.

http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible

Phân bổ bộ nhớ động mục đích chung khi chạy trong trò chơi hoặc mô phỏng nên tránh. Vấn đề không phải lúc nào cũng bị phân mảnh hoặc một nút cổ chai lớn (cả hai lý do hợp lệ để tránh) nhưng cũng thực tế là lượng thời gian thường không xác định. Một chiến lược phân bổ bộ nhớ cụ thể hơn cho miền như 'tổng hợp' hoặc 'rập khuôn' sẽ có lợi ở đây.

http://g.oswego.edu/dl/html/malloc.html

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