Ist es möglich, den von C's alloca() zugewiesenen Speicher explizit freizugeben, bevor die aktuelle Funktion beendet wird? Wenn ja, wie?
Antworten
Zu viele Anzeigen?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.
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.
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
- See previous answers
- Weitere Antworten anzeigen
0 Stimmen
Können Sie Ihre Motivation erklären? Warum möchten Sie den zugewiesenen Platz vor der Rückkehr freigeben?