2010-12-15 11 views
7

W C (lub C++) Zastanawiam się, czy można częściowo zwolnić blok pamięci.Czy można częściowo zwolnić pamięć?

Na przykład, załóżmy, że tworzymy tablicę liczb całkowitych a o rozmiarze 100,

int * a = malloc(sizeof(int)*100); 

a później chcemy zmienić rozmiar a tak, że posiada 20 ints zamiast 100.

Czy istnieje sposób na uwolnienie tylko ostatniego 80 * sizeof (int) bajtów z a? Na przykład, jeśli zadzwonimy do realloc, czy zrobi to automatycznie?

  • Szukam rozwiązania, które nie wymaga przenoszenia/kopiowania pierwszych 20 elementów.
  • Możesz również wyjaśnić, dlaczego byłoby to złe, gdyby było to możliwe, lub dlaczego zdolność do tego nie była zawarta w żadnym z tych języków?

Odpowiedz

14

Można użyć realloc, ale zdecydowanie powinieneś rozważyć użycie kontenerów STL zamiast ręcznego przydzielania pamięci.

+1

Nie przydziela ponownie kopii tablicy, a następnie zwolnić oryginał? – Cam

+4

@Cam, nie. Dozwolone jest (i często będzie) zmniejszenie istniejącego regionu. –

+4

@ watson1180: Racja, ale to nic nie znaczy. Zasadniczo realloc może zostać zaimplementowany, aby uzyskać czas O (n!^99) i zawsze przydzielić 500 razy potrzebną pamięć, ale z pewnością nie uwzględniamy tego przy podejmowaniu decyzji dotyczących ponownego przydziału. – Cam

3

Preferujemy kontenery RAII do surowych wskaźników w C++.

#include <vector> 

// ... 

{ 
    std::vector<int> a(100) 
    // ... 
    std::vector<int>(a.begin(), a.begin() + 20).swap(a); 
} 
+4

Należy zauważyć, że to naprawdę nie "częściowo zwalnia pamięć". Przydziela nowy blok o żądanym rozmiarze, kopiuje zawartość z oryginalnego bloku, a następnie uwalnia oryginalny blok. –

+1

Co jest nie tak z '.resize (20)'? (Jestem noobem C++) – dreamlax

+1

resize() nie musi dostosowywać przydzielonej pamięci. Nawet clear() nie musi. –

2

Wolałbym używać std::vector. Załóżmy włączyć C++ 0x:

std::vector<int> vec(20); 
vec.reserve(100); 

// do something 

vec.shrink_to_fit(); 

Od n3092 (nie tak ostateczny projekt, muszę dostać świeżej kopii na tym komputerze):

void shrink_to_fit();

Uwagi: shrink_to_fit jest zakaz -zwracanie żądania zmniejszenia użycia pamięci. [Uwaga: Żądanie nie jest wiążące, aby umożliwić szerokość geograficzną dla optymalizacji związanych z realizacją. -end note]

Powiązane problemy