2012-11-09 17 views
9

Se faccio questo: -do std :: function e std :: bind fanno allocazione di memoria dinamica?

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

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

e in alcuni Stati di "Thing"

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

Ha sia la chiamata a std :: bind o l'uso di std :: funzione <> causa qualsiasi allocazione di memoria dinamica usando nuovo o altro? O tutto lo spazio allocato è in fase di compilazione? Se lo standard non dice nulla, in Visual Studio 2012, poiché il mio programma dovrà solo essere costruito lì, e per l'efficienza probabilmente dovrò evitare allocazioni di memoria dinamica nel luogo in cui sto pensando di usare questo meccanismo.

+6

"per l'efficienza io probabilmente" non si deve fare ipotesi su efficienza del genere. – slaphappy

+5

L'uso di 'std :: list' causerà un'allocazione di memoria ogni volta che si aggiunge un elemento all'elenco. –

+1

Ahahahahahaha evitando allocazioni dinamiche durante l'utilizzo di std :: list –

risposta

14

Lo standard non specifica, ma in generale è facile vedere che std::function deve allocare memoria almeno in alcuni casi:

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

D'altra parte è possibile per esso per evitare assegnazione in almeno alcuni casi collocando l'oggetto funzione all'interno di un buffer preallocato all'interno dell'impronta dell'oggetto function; ovviamente c'è un compromesso in quanto ciò potrebbe rendere altri usi più memoria dello stack. Una buona implementazione sarebbe in grado di evitare l'allocazione di memoria quando si memorizza un puntatore a funzione grezza in un oggetto , e probabilmente anche per un mem_fn, ma è meno probabile che lo faccia per un bind.

Ad esempio, libstdC++ (g ++) Inlines (Functor) puntatori all'oggetto, puntatori a funzione, e (non virtuali) puntatori a funzioni membro, nonché qualsiasi altra cosa che sarebbe adattano nello stesso spazio, ad esempio funtori stateless (union _Nocopy_types).

Se è possibile, invertendo il flusso di controllo per accettare oggetti funtore su modelli invece di function si può evitare qualsiasi allocazione di memoria in più:

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

Ok, questo ha senso, grazie – jcoder

0

io non sono sicuro di questo. Immagino, come suggerisce ecatmur, dipenda dall'implementazione di std per quella piattaforma. Per problemi simili ho avuto un buon successo usando questa implementazione dal progetto di codice. Supporta un buon numero di piattaforme. Molto ben documentata e nessuna allocazione dinamica della memoria.

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

scopo generale allocazione dinamica della memoria in fase di esecuzione in giochi o simulazione dovrebbe essere evitato. Il problema non è sempre la frammentazione o un grande collo di bottiglia (entrambi validi motivi per evitare), ma anche il fatto che la quantità di tempo è spesso non deterministica. Una strategia di allocazione della memoria più specifica del dominio come "pooling" o "framing" sarebbe vantaggiosa qui.

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

Problemi correlati