2010-12-15 6 views
7

In C (oder C++) frage ich mich, ob es möglich ist, einen Speicherblock teilweise freizugeben.Ist es möglich, Speicher teilweise freizugeben?

Beispiel: Angenommen, wir eine Reihe von ganzen Zahlen a der Größe 100, erstellen

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

und dann später wollen wir a so skalieren, dass es 20 ints hält statt 100.

Gibt es eine Möglichkeit, nur die letzten 80 * sizeof (int) Bytes von a freizugeben? Wenn wir zum Beispiel realloc aufrufen, wird es das automatisch tun?

  • Ich bin auf der Suche nach einer Lösung, die nicht erfordert, die ersten 20 Ints zu verschieben/kopieren.
  • Alternativ können Sie entweder erklären, warum es schlecht wäre, wenn dies möglich wäre, oder warum die Fähigkeit dazu nicht in beiden Sprachen enthalten ist?
  • Antwort

    14

    Sie können realloc verwenden, aber Sie sollten definitiv die Verwendung von STL-Containern in Betracht ziehen, anstatt Speicher manuell zuzuweisen.

    +1

    Realloc nicht kopieren das Array und dann das Original frei? – Cam

    +4

    @Cam, nein. Es ist erlaubt (und wird oft) die bestehende Region zu verkleinern. –

    +4

    @ watson1180: Richtig, aber das allein bedeutet nichts. Im Prinzip könnte Realloc implementiert werden, um O (n!^99) Zeit zu nehmen und immer das 500-fache des notwendigen Speichers zuzuteilen, aber wir berücksichtigen das bei Entscheidungen, die Realloc betreffen, nicht. – Cam

    3

    Wir bevorzugen RAII-Container zu rohen Zeigern in C++.

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

    Es sollte angemerkt werden, dass dies nicht wirklich "teilweise Speicher freigeben". Dies weist einen neuen Block der gewünschten Größe zu, kopiert den Inhalt von dem ursprünglichen Block und gibt dann den ursprünglichen Block frei. –

    +1

    Was ist mit '.resize (20)' falsch? (Ich bin ein C++ - Noob) – dreamlax

    +1

    resize() muss den zugewiesenen Speicher nicht anpassen. Auch clear() muss nicht. –

    2

    Ich würde lieber eine std::vector verwenden. Lassen Sie uns C ermöglichen ++ 0x:

    std::vector<int> vec(20); 
    vec.reserve(100); 
    
    // do something 
    
    vec.shrink_to_fit(); 
    

    Von n3092 (nicht der so endgültigen Entwurf, ich brauche eine neue Kopie auf diesem PC zu bekommen):

    void shrink_to_fit();

    Bemerkungen: shrink_to_fit ist ein nicht Binding-Anfrage, um Speicherverbrauch zu reduzieren. [Hinweis: Die Anfrage ist nicht bindend, um den Spielraum für implementierungsspezifische Optimierungen zu ermöglichen. -Ende]