Kinexity Temat założony przez niniejszego użytkownika |
Problem z alokacją niezainicjalizowanej pamięci » 2018-06-29 22:03:49 Witam wszystkich. Mam taki kod: template < typename T > void funkcja( T * ptr, size_t size ) { unique_ptr < T[] > delete_ptr = unique_ptr < T[] >(( T * )( new uint8_t[ size * sizeof( T ) ] ) ); }; Ta oryginalna linia kodu ma na celu zaalokowanie pamięci bez inicjalizowania. Z kompilacją nie ma problemów, za to w trakcie działania program się wywala z błędem krytycznym. Nieobsłużony wyjątek w lokalizacji 0x00007FFB30B3D75E (ucrtbase.dll): Zażądano zakończenia programu z błędem krytycznym. Byłbym wdzięczny za wskazanie przyczyny problemu lub pomoc w znalezieniu alternatywnego rozwiązania. |
|
pekfos |
» 2018-06-29 22:55:47 Takie użycie unique_ptr<> jest błędne. Gdy dojdzie do usunięcia pamięci przy wyjściu z zakresu, będziesz mieć problemy, jeśli pamięć nie jest w poprawnym stanie by ją usuwać jako T[] (Usuwanie pamięci jako inny typ, jeśli ten typ nie jest klasą bazową faktycznego typu, ma niezdefiniowane zachowanie). Powinieneś mieć unique_ptr<uint8_t[]>. |
|
Kinexity Temat założony przez niniejszego użytkownika |
» 2018-06-29 23:45:10 Wiem o tym. Dalej w tej funkcji do zaalokowanej pamięci kopiowane są gotowe obiekty z innego fragmentu pamięci. Tak wygląda kombinowanie z programowaniem w CUDA. Jak potrzeba to mogę wrzucić pełny kod i wytłumaczyć czemu robię coś tak dziwnego. |
|
pekfos |
» 2018-06-30 00:45:26 To ma niezdefiniowane zachowanie, ale jak chcesz, to wytłumacz po co to robisz. To co usiłujesz robić, robi wewnętrznie std::vector<>. Dlaczego nie użyjesz tego? |
|
Kinexity Temat założony przez niniejszego użytkownika |
» 2018-06-30 08:34:19 template < typename T > void cudaObjectArrayFree( T * ptr, size_t size ) { unique_ptr < T[] > delete_ptr = unique_ptr < T[] >(( T * )( new uint8_t[ size * sizeof( T ) ] ) ); memcpy( delete_ptr.get(), ptr, size ); cudaFree( ptr ); }; W przypadku programowania w CUDA można zaalokować pamięć równocześnie w RAM i VRAM, która będzie się automatycznie synchronizowała. Niestety jej alokowanie działa jak alokowanie w stylu C - przydzielany jest po prostu fragment pamięci bez wywoływania konstruktorów i destruktorów. Powyższy kod ma tworzyć pustą tablicę, kopiować do niej obiekty, usuwać tzw. pamięć zarządzaną i potem wywołać destruktory na skopiowanych obiektach (które mają swoje zasoby do zwolnienia). |
|
pekfos |
» 2018-06-30 09:41:13 Skoro korzystasz z unified memory, to po co chcesz kopiować obiekty do tymczasowej tablicy tylko po to, by je usunąć? Gdzie w tym sens? Dlaczego nie użyjesz std::vector<>? |
|
Kinexity Temat założony przez niniejszego użytkownika |
» 2018-06-30 15:06:06 Każdy z obiektów alokuje sobie dodatkowo pamięć przy pomocy unique_ptr, która musi zostać zwolniona przez wywołanie destruktora klasy. Funkcja cudaFree po prostu zwalnia pamięć nie wywołując destruktorów, i dlatego właśnie tak "brutalnie" kopiuję te obiekty i dzięki temu ich destruktory są wywoływane. |
|
pekfos |
» 2018-06-30 16:52:03 cudaFree() i wywoływanie destruktorów nie wykluczają się. Poczytaj o placement new. I o drugim parametrze szablonu std::vector<>. Każdy z obiektów alokuje sobie dodatkowo pamięć przy pomocy unique_ptr, która musi zostać zwolniona przez wywołanie destruktora klasy. |
Jeśli ta pamięć nie jest używana wyłącznie w kodzie hosta, to też powinieneś zaalokować pamięć CUDA. |
|
« 1 » |