Viele interessante Antworten auf diese "alte" Frage, sogar einige relativ neue Antworten, aber ich habe keine gefunden, die dies erwähnen ...
Bei sachgemäßer und sorgfältiger Verwendung kann die konsequente Verwendung alloca()
(möglicherweise anwendungsweit) zur Verarbeitung kleiner Zuordnungen variabler Länge (oder C99-VLAs, sofern verfügbar) zu einem geringeren Gesamtstapelwachstum führen als eine ansonsten gleichwertige Implementierung mit übergroßen lokalen Arrays fester Länge . So alloca()
kann es sich gut für die Stapel , wenn Sie es sorgfältig verwenden.
Ich fand dieses Zitat in ... OK, ich habe dieses Zitat erfunden. Aber wirklich, denk darüber nach ...
@j_random_hacker ist in seinen Kommentaren unter anderen Antworten sehr richtig: Wenn Sie die Verwendung von alloca()
übergroßen lokalen Arrays vermeiden, wird Ihr Programm nicht vor Stapelüberläufen sicherer (es sei denn, Ihr Compiler ist alt genug, um das Inlining von Funktionen zu ermöglichen, die alloca()
in diesem Fall verwendet werden sollten Upgrade oder es sei denn, Sie verwenden alloca()
Inside-Loops. In diesem Fall sollten Sie ... keine alloca()
Inside-Loops verwenden.
Ich habe an Desktop / Server-Umgebungen und eingebetteten Systemen gearbeitet. Viele eingebettete Systeme verwenden überhaupt keinen Heap (sie verknüpfen ihn nicht einmal), aus Gründen, die die Wahrnehmung einschließen, dass dynamisch zugewiesener Speicher aufgrund des Risikos von Speicherverlusten in einer Anwendung, die niemals funktioniert, böse ist Neustarts über Jahre hinweg oder die vernünftigere Rechtfertigung, dass dynamischer Speicher gefährlich ist, da nicht sicher bekannt sein kann, dass eine Anwendung ihren Heap niemals bis zur Erschöpfung des falschen Speichers fragmentieren wird. Eingebettete Programmierer haben also nur wenige Alternativen.
alloca()
(oder VLAs) sind möglicherweise genau das richtige Werkzeug für den Job.
Ich habe immer wieder gesehen, wie ein Programmierer einen vom Stapel zugewiesenen Puffer "groß genug macht, um jeden möglichen Fall zu behandeln". In einem tief verschachtelten Aufrufbaum führt die wiederholte Verwendung dieses (Anti -?) Musters zu einer übertriebenen Stapelverwendung. (Stellen Sie sich einen Anrufbaum mit einer Tiefe von 20 Ebenen vor, bei dem die Funktion auf jeder Ebene aus unterschiedlichen Gründen blind einen Puffer von 1024 Bytes "nur um sicher zu gehen" zu viel zuweist, wenn im Allgemeinen nur 16 oder weniger davon verwendet werden, und dies nur in sehr In seltenen Fällen kann mehr verwendet werden.) Eine Alternative ist die Verwendungalloca()
oder VLAs und weisen nur so viel Stapelspeicher zu, wie Ihre Funktion benötigt, um eine unnötige Belastung des Stapels zu vermeiden. Wenn eine Funktion im Aufrufbaum eine überdurchschnittliche Zuweisung benötigt, verwenden andere im Aufrufbaum hoffentlich immer noch ihre normalen kleinen Zuordnungen, und die Gesamtnutzung des Anwendungsstapels ist erheblich geringer, als wenn jede Funktion einen lokalen Puffer blind überbelegt hätte .
Aber wenn Sie sich entscheiden zu verwenden alloca()
...
Basierend auf anderen Antworten auf dieser Seite scheint es, dass VLAs sicher sein sollten (sie setzen keine Stapelzuweisungen zusammen, wenn sie aus einer Schleife heraus aufgerufen werden), aber wenn Sie sie verwenden alloca()
, achten Sie darauf , sie nicht innerhalb einer Schleife zu verwenden, und machen Sie Stellen Sie sicher, dass Ihre Funktion nicht eingebunden werden kann, wenn die Möglichkeit besteht, dass sie in der Schleife einer anderen Funktion aufgerufen wird.