2017-02-01 17 views
10

Jestem nowy w C++, pochodzący z C#. Oto kod:C++ Usuń tablicę, nawet jeśli wystąpi błąd

void function(int n) 
{ 
    double* array = new double[n]; 

    //some work that can return or throw an exception 
    //... 

    delete[] array; 
    return; 
} 

wiem nie ma C# using odpowiednik w C++.

Czy istnieje prosty i elegancki sposób na zapewnienie, że pamięć zostanie wydana, co się dzieje?

+6

Tak, jest. Uruchom wyszukiwanie w Google na "inteligentne wskaźniki". –

+6

Lub jeszcze lepiej ['std :: array'] (http://en.cppreference.com/w/cpp/container/array) (lub ewentualnie [' std :: vector'] (http: //en.cppreference .com/w/cpp/container/vector)). –

+4

Czytaj na idiomie RAII, używanym w Rust i C++. –

Odpowiedz

13

W C++, kod wyglądałby następująco:

#include <vector> 

void function() 
{ 
    std::vector<double> array(100); 

    //some work that can return when or throw an exception 
    //... 

    return; 
} 

Jeśli naprawdę nie chcesz zainicjować elementów tablicy i nie ma potrzeby, aby zmienić rozmiar tablicy i nie trzeba iteratory, ty można również użyć:

#include <memory> 

void function() 
{ 
    std::unique_ptr<double[]> array(new double[100]); 

    //some work that can return when or throw an exception 
    //... 

    return; 
} 

w obu przypadkach masz dostęp do poszczególnych elementów tablicy z array[0], array[1] itp

Wreszcie, jeśli nie trzeba t o przeniesienie własności danych z funkcji, znać rozmiar tablicy w czasie kompilacji, a rozmiar nie jest zbyt duża, można również rozważyć bezpośredni przedmiot tablicy:

void function() 
{ 
    double array[100]; // uninitialized, add " = {}" to zero-initialize 

    // or: 

    std::array<double, 100> array; // ditto 

    //some work that can return when or throw an exception 
    //... 

    return; 
} 
+0

'std :: valarray ' może być również przydatny w zależności od konkretnego rozwiązania problemu. – Andrew

+0

Myślę, że byłoby miło wspomnieć 'std :: array' zamiast surowych tablic. –

+0

@GuillaumeRacicot: Rozmiar 'std :: array' musi być znany podczas kompilacji, a OP nie zna rozmiaru do czasu wykonania (było to ukryte w komentarzu do OP:" ludzie, którzy odpowiedzieli: przepraszam za wprowadzający w błąd przykład, rozmiar tablicy nie jest znany podczas kompilacji ") – AndyG

10

zmienne automatyczne są zniszczone automatycznie na końcu zakresu, czy to ze względu na powrót lub rzut:

{ 
    double array[100]; 
    throw 1; // no memory leaked 
} 

żal mylącego przykład, wielkość matrycy nie jest znana w czasie kompilacji

W takim przypadku potrzebna jest tablica dynamiczna. Popularnym rozwiązaniem do czyszczenia zasobów, takich jak pamięć dynamiczna, jest zawijanie wskaźnika (lub obsługi lub deskryptora w zależności od typu zasobu) w klasie, która pozyskuje zasoby podczas inicjowania i zwalnia po zniszczeniu. Następnie możesz utworzyć automatyczną zmienną tego typu opakowania. Ten wzorzec nazywa się "Pozyskiwanie zasobów to inicjalizacja" lub skrót RAII.

Nie musisz jednak pisać własnego opakowania RAII dla tablicy dynamicznej. Biblioteka standardowa objęła Cię: std::vector

Powiązane problemy