9 Stimmen

Freigabe von zugewiesenem Speicher

Ist es möglich, den von C's alloca() zugewiesenen Speicher explizit freizugeben, bevor die aktuelle Funktion beendet wird? Wenn ja, wie?

0 Stimmen

Können Sie Ihre Motivation erklären? Warum möchten Sie den zugewiesenen Platz vor der Rückkehr freigeben?

1voto

paxdiablo Punkte 809679

Nein, denn er wird zusammen mit den lokalen Variablen auf dem Stack zugewiesen. Wenn Sie Speicher benötigen, den Sie explizit freigeben können, verwenden Sie eine der Funktionen für die dynamische Speicherzuweisung.

Es gibt keinen Hybrid, der es Ihnen erlaubt, explizit frei UND auch beim Verlassen der Funktion automatisch freigeben, zumindest nicht im Standard.

1voto

Luke Lee Punkte 250

Ja, aber das hängt von der Implementierung von alloca() ab. Eine vernünftige und einfache Implementierung von alloca() besteht darin, dass der neu zugewiesene Block, der auf Oberkante Stapel durch Anpassung des Stapelzeigers. Um diesen Speicher freizugeben, müssen wir daher nur eine negativ Zuteilung (aber Sie müssen die tatsächliche Implementierung von alloca() studieren), lassen Sie uns dies mit folgendem Beispiel verifizieren nicht tragbar Code zum Beispiel:

#include <stdio.h>
#include <alloca.h>

int main()
{
  unsigned long p0, p1, p2;
  p0=(unsigned long)alloca(0);
  p1=(unsigned long)alloca((size_t) 0x1000);
  p2=(unsigned long)alloca((size_t)-0x1000);
  printf( "p0=%lX, p1=%lX, p2=%lX\n", p0, p1, p2 );
  return 0;
}

Auf einer alten x64-Maschine mit clang 2.9, ist eine Beispielausgabe:

p0=7FFF2C75B89F, p1=7FFF2C75A89F, p2=7FFF2C75B89F

Wir kennen also die Umsetzung nicht das Argument -0x1000 validieren, da sonst der Wert ohne Vorzeichen eine sehr große ganze Zahl ist. Der Stapelzeiger war ursprünglich 0x...B89F; da dieser Stapel nach oben wächst alloca(0x1000) daher den Stapelzeiger ändern auf bis (0x...B89F - 0x1000) = 0x...A89F. Nach der negativen Zuweisung (0xA89F - (-0x1000)) ging der Stapelzeiger zurück auf 0x...B89F.

Mit gcc 4.8.3 ist jedoch eine Beispielausgabe:

p0=7FFFA3E27A90, p1=7FFFA3E26A80, p2=7FFFA3E27A70

In /usr/include/alloca.h finden wir:

#ifdef  __GNUC__
# define alloca(size)   __builtin_alloca (size)
#endif /* GCC.  */

Wir wissen also, dass die eingebaute alloca-Funktion von gcc 4.8.3 etwas Ähnliches macht, außer dass sie zusätzliche 0x10 Bytes als Sicherheitsspanne zuweist. Bei negativer Allokation nimmt sie immer noch an, dass sie nach oben wächst und versucht daher, 0x10 zusätzliche Bytes (- 0x10) zu reservieren, also p2= 0x...6A80 - (-0x1000) - 0x10 = 0x...7A70. Seien Sie also besonders vorsichtig.

-1voto

Sie müssen keine benutzerdefinierten Programme schreiben. freea(...) Art von Funktion noch VLA verwenden. Der auf dem Stack zugewiesene Speicher kann sowohl in C als auch in C++ problemlos freigegeben werden (C++ unterstützt keine VLAs). Die alloca(...) auf dem Stack alloziert, richtig? Das bedeutet, dass der Speicher deallokiert wird, wenn er den Gültigkeitsbereich verlässt... also verwenden Sie einfach Gültigkeitsbereiche!

#include <alloca.h>

int main()
{
    {
        void* ptr = alloca(1024);

        // do your stuff

    } // memory is deallocated here

    return 0;
}

Wie Sie aus dem Godbolt-Online-Compiler ersehen können, macht der Assembler (ohne Optimierung) alles richtig: https://godbolt.org/z/Gn5YMa

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X