Powodem, dla którego muszę o to zapytać, jest konieczność przechowywania std::function
w wektorze, a wewnętrzny wektor, który mamy w firmie, w zasadzie wykonuje realloc, jeśli potrzebuje więcej pamięci . (Zasadniczo tylko memcpy
, bez operatora kopiowania/przenoszenia)Dlaczego nie możemy trywialnie skopiować std :: function
Oznacza to, że wszystkie elementy, które możemy umieścić w naszym pojemniku, muszą być trywialnie kopiowalne.
Oto niektóre kodu do wykazania problematyczny egzemplarz miałem:
void* func1Buffer = malloc(sizeof(std::function<void(int)>));
std::function<void(int)>* func1p = new (func1Buffer) std::function<void(int)>();
std::function<void(int)>* func2p = nullptr;
*func1p = [](int) {};
char func2Buffer[sizeof(*func1p)];
memcpy(&func2Buffer, func1p, sizeof(*func1p));
func2p = (std::function<void(int)>*)(func2Buffer);
// func2p is still valid here
(*func2p)(10);
free(func1Buffer);
// func2p is now invalid, even without std::function<void(int)> desctructor get triggered
(*func2p)(10);
rozumiem powinniśmy wspierać Kopiuj/przenieś elementu w celu przechowywania std::function
bezpiecznie. Ale nadal jestem bardzo ciekawy, jaka jest bezpośrednia przyczyna nieprawidłowej kopii powyżej: std::function
.
--------------------------------------------- ------- UpdateLine ------------------------------------------ ----------
Zaktualizowano przykład kodu.
Znalazłem bezpośredni powód tego błędu, poprzez debugowanie naszego wewnętrznego w domu więcej.
trywialnie kopiowane std::function
ma pewną zależność od oryginalnej pamięci obiektu, usuń oryginalną pamięć będzie kosza źle skopiowany std::function
nawet bez zniszczenie oryginalnego obiektu.
Dziękuję za odpowiedź wszystkich na ten wpis. To wszystko jest wartościowym wkładem. :)
* Dlaczego nie możemy trywialnie skopiować std :: function *? Ponieważ standard definiuje to w ten sposób. –
Dopóki używasz niezapisujących lambd, możesz uciec z przechowywaniem wskaźników funkcji w wektorze. – NathanOliver
niektóre aktualizacje tutaj, zrobiłem jakiś błąd lokalnie i kod przykładowy podaję w moim pytaniu faktycznie działa. –