Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Problem z alokacją niezainicjalizowanej pamięci

Ostatnio zmodyfikowano 2018-06-30 16:52
Autor Wiadomość
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:
C/C++
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 ) ] ) ); //tu wywala błąd
    //cośtam dalej
};
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.
P-171713
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[]>.
P-171715
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.
P-171716
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?
P-171717
Kinexity
Temat założony przez niniejszego użytkownika
» 2018-06-30 08:34:19
C/C++
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 ) ] ) ); //tu wywala błąd
    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).
P-171718
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<>?
P-171719
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.
P-171727
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.
P-171730
« 1 »
  Strona 1 z 1