2009-05-13 14 views
9

Kiedy skompilowałem kod używając nazwy tablicy jako wskaźnika i usunąłem nazwę tablicy używając delete, otrzymałem ostrzeżenie o usunięciu tablicy bez użycia formularza tablicy (nie pamiętam dokładnego sformułowania).Co to jest forma tablicy "usuń"?

Kod podstawowego:

int data[5]; 
delete data; 

Więc, jaka jest forma tablicę usunąć?

+3

To wywołuje niezdefiniowane zachowanie, ponieważ tablica nie została przydzielona za pomocą nowego []. –

Odpowiedz

33

Formularz tablica kasowania jest:

delete [] data; 

Edit: Ale jak inni zwrócili uwagę, nie powinno być wywołanie delete dla danych zdefiniowane tak:

int data[5]; 

You powinien wywoływać tylko wtedy, gdy przydzielisz pamięć za pomocą new w ten sposób:

int *data = new int[5]; 
+2

Ale jego int dane [5] nie zostały przydzielone przez operatora new(), więc nie ma poprawnej formy operatora delete(), które można wywołać. – RBerteig

+1

Interesujące ... odpowiedź jest poprawna, ale och tak źle. Jak zdobył 17 głosów? –

+2

Tak łatwo jest odpowiedzieć na pytanie, które zostało zadane, zamiast na pytanie, które powinno zostać zadane. Zwłaszcza gdy powtórzył się zarówno w tytule, jak iw ostatnim zdaniu. – RBerteig

0

Tak jak RichieHindle stwierdził powyżej, aby zwolnić przestrzeń przydzieloną dynamicznie dla tablicy wskazanej przez data, należy umieścić dwa nawiasy [] między słowem zastrzeżonym delete a wskaźnikiem na początku przydzielonego miejsca. Ponieważ data może wskazywać na pojedynczą int w pamięci, jak również na pierwszy element w tablicy, jest to jedyny sposób, w jaki kompilator wie, że chcesz usunąć cały fragment pamięci. Jeśli nie zrobisz tego we właściwy sposób, zachowanie jest "nieokreślone" (Stroustrup, The C++ Programming Language).

2

Przedstawiony kod ma tablicę albo na stosie, albo w zainicjalizowanej części segmentu danych, tzn. Nie zwalniasz jej (która, jak wspomniano przez innych, byłaby "niezdefiniowanym zachowaniem"). w "wolnym sklepie" możesz to zrobić za pomocą delete [] data.

13

Albo chcą:

int *data = new int[5]; 
... // time passes, stuff happens to data[] 
delete[] data; 

lub

int data[5]; 
... // time passes, stuff happens to data[] 
// note no delete of data 

Zasadą jest genera: tylko zastosować delete do pamięci, która pochodziła z new. Jeśli użyto formularza tablicowego new, musisz użyć , aby dopasować formularz tablicy delete. Jeśli zostało użyte miejsce docelowe new, to albo nigdy nie wołaj numeru delete, albo użyj pasującego miejsca docelowego delete.

Ponieważ zmienna int data[5] jest tablicą alokowaną statycznie, nie można jej przekazać żadnej formie operatora delete.

3

Jako drugi powiedział, należy skorzystać z formularza wektorowych Usuń:

void some_func(size_t n) 
{ 
    int* data = new int[n]; 

    . . . // do stuff with the array 

    delete [] data; // Explicitly free memory 
} 

Bądź bardzo ostrożny z tym, ponieważ niektóre kompilatory nie będzie ostrzec.

Nawet bardzo rzadko istnieje potrzeba użycia wektora nowy/usunąć.Zastanów się, czy Twój kod może zostać zmieniony, aby skorzystać z std :: vector:

void some_func(size_t n) 
{ 
    std::vector<int> data(n); 

    . . . // do stuff with the array 

} // memory held by data will be freed here automatically 

A jeśli masz do czynienia z pamięcią w zakresie lokalnym, należy rozważyć użycie STLSoft „s auto_buffer, który przydzieli z wewnętrznym buforze (przeznaczone na stosie, jako część instancji), jeśli to możliwe, tylko idzie do sterty, jeśli nie może ona:

void some_func(size_t n) 
{ 
    stlsoft::auto_buffer<int, 10> data(n); // only allocates if n > 10 

    . . . // do stuff with the array 

} // memory held by data will be freed here automatically, if any was allocated 

Czytaj more about auto_buffer.