2014-08-31 12 views
6

Próbuję dowiedzieć się więcej o pulach pamięci w C++ dla lepszej szybkości i możliwości debugowania. Podążałem za podejściem tutaj: http://oroboro.com/overloading-operator-new/. Tak już przeciążony, new[]new, delete i delete[] tak:Globalne przeciążenie delete [] nie jest wywoływane w bibliotekach innych firm

inline void* operator new  (size_t size) { return myAlloc(size); } 
inline void* operator new[] (size_t size) { return myAlloc(size); } 
inline void operator delete (void* ptr ) { myFree(ptr); } 
inline void operator delete[](void* ptr ) { myFree(ptr); } 

Lubię że biblioteki innych firm są skierowane do tej wersji new, ale wpadłem na problem. Robię aplikację DirectX, która używa DXUT. Kompiluję DXUT oddzielnie od mojego projektu. W końcu nazywa to:

std::unique_ptr<D3D11_SUBRESOURCE_DATA[]> initData(new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ]); 

Gdy ten unikalny wskaźnik wychodzi z zakresu, to zawiesza się na wezwanie do delete[] _Ptr, które nie przechodzą przez mojego przeciążonego operatora. Próbowałem debugowania implementacji puli pamięci przez dodanie int* dummy = new int[10]; delete[] dummy; w moim main. Budowanie projektu spowodowało błąd, ale czysty budynek działał dobrze. Ku mojemu zaskoczeniu wszystko działało, łącznie z awarią linii DXUT!

Pytanie 1: Co dokładnie się stało, gdy dodałem linię debugowania, która rozwiązała problem? Chyba z jakiegoś powodu mój operator delete [] nie był znany, dopóki nie wywołałem go we własnym kodzie aplikacji? Czy to gwarantuje naprawienie problemu, czy może to tylko głupie szczęście?

Pytanie 2: Zauważyłem, że new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ] nie zadzwonił bezpośrednio pod mój operator new[], ale ostatecznie nazwał mój operator new (bez nawiasów). Nadal wywołuje operatora delete[] na wskaźniku. Czy to stanowi problem? Czy muszę dodać odpowiednie przeciążenie tak, aby mój operator new[] został wywołany lub czy to zachowanie jest w porządku?

Dla porównania, operator new[] przeciążenie, które nazwano było:

void * __CRTDECL operator new[](::size_t count, const std::nothrow_t& x) 
_THROW0() 
{ // Try to allocate count bytes for an array 
    return (operator new(count, x)); 
} 

Odpowiedz

4

Pytanie 1: Co dokładnie się stało, kiedy dodałem linię debugowania że naprawił problem? Chyba z jakiegoś powodu mój operator delete [] nie był znany, dopóki nie wywołałem go w moim własnym kodzie aplikacji? Czy to jest gwarantowane , aby naprawić problem, czy jest to po prostu głupie szczęście?

§3.2 [basic.def.odr]/P4:

funkcji inline jest określony w każdej jednostki translacji, w którym jest ona ODR wykorzystane.

Brzmi to, że kompilator nie wygeneruje kod dla globalnej operator delete[] ponieważ nie jest używany w jednostce głównej tłumaczeń i jest oznaczony inline (czyli kompilator można zakładać, że każda jednostka tłumaczenie który wykorzystuje je będzie miał ich definicja). Jednak twoja osobno skompilowana biblioteka nie ma definicji tych funkcji, a na końcu używasz domyślnych bibliotek standardowych. Uczynienie ich non-inline powinno naprawić problem.

Pytanie 2: Zauważyłem, że new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ] nie zadzwonił mój operator new[] bezpośrednio, ale w końcu zadzwonił do mojego operator new (nie nawiasach).Nadal wywołuje operatora delete[] na wskaźniku. Czy stanowi to problem? Czy muszę dodać odpowiednie przeciążenie, takie jak , które nazywa się mój operator new[] lub czy to zachowanie jest w porządku?

Wersje domyślne zarówno rzucania i nonthrowing wersje operator new [], jak również wersję nonthrowing z operator new, są określone zadzwonić wersję rzucanie operator new uzyskanie pamięć. Więc jesteś tam bezpieczny. Jednak twoje definicje z operator new są prawdopodobnie błędne. Muszą zwrócić poprawny wskaźnik lub rzucić wyjątek. Zwracanie wskaźnika pustego jest niedozwolone.

+0

Usuwanie wpisu i wstawienie kodu do pliku implementacji zamiast do nagłówka! Zastanawiam się, dlaczego link, który skopiowałem, nie wspominał o tym. – DSM

Powiązane problemy