Aufruf an _freea wirklich notwendig?

8

Ich entwickle unter Windows mit DevStudio, in C / C ++ unmanaged.

Ich möchte etwas Speicher auf dem Stack statt des Heaps reservieren, weil ich nicht mit der manuellen Freigabe dieses Speichers fertig werden will (ich kenne Smart-Pointer und all diese Dinge. Ich habe einen sehr spezifischen Fall von Speicher Zuordnung, mit der ich mich auseinandersetzen muss), ähnlich der Verwendung von A2W () - und W2A () - Makros.

_alloca macht das, aber es ist veraltet. Es wird empfohlen stattdessen malloca zu verwenden. Aber _malloca Dokumentation sagt, dass ein Anruf zu

Philibert Perusse 09.04.2009, 15:59
quelle

6 Antworten

13

Es ist immer wichtig, _freea nach jedem Aufruf von _malloca aufzurufen.

_malloca ist wie _alloca, fügt jedoch zusätzliche Sicherheitsüberprüfungen und Verbesserungen für Ihren Schutz hinzu. Daher ist es möglich, dass _malloca auf dem Heap anstelle des Stacks zugewiesen wird. Wenn dies geschieht und Sie _freea nicht aufrufen, erhalten Sie einen Speicherverlust.

Im Debug-Modus wird _malloca IMMER auf dem Heap allokiert, sollte also ebenfalls freigegeben werden.

Suchen Sie nach _ALLOCA_S_THRESHOLD, um zu erfahren, wie die Schwellenwerte funktionieren und warum _malloca anstelle von _alloca vorhanden ist, und das sollte sinnvoll sein.

Bearbeiten:

Es gibt Kommentare, die darauf hindeuten, dass die Person nur auf dem Heap allokiert und intelligente Zeiger usw. verwendet.

Stackzuweisungen, die _malloca Ihnen zur Verfügung stellt, haben Vorteile. Es gibt also Gründe, dies zu tun. _alloca wird auf die gleiche Weise funktionieren, aber es ist viel wahrscheinlicher, dass es zu einem Stack-Überlauf oder anderen Problemen kommt, und bietet leider keine schönen Ausnahmen, sondern neigt eher dazu, den Prozess einfach abzubrechen. _malloca ist in dieser Hinsicht viel sicherer und schützt Sie, aber die Kosten sind, dass Sie noch Ihren Speicher mit _freea freigeben müssen, da es möglich ist (aber im Freigabemodus unwahrscheinlich), dass _malloca beschließen wird, auf dem Heap anstelle des Stapels zuzuweisen.

Wenn Sie nur vermeiden möchten, dass Sie Speicher freigeben müssen, würde ich Ihnen einen intelligenten Zeiger empfehlen, der die Speicherfreigabe für Sie übernimmt, wenn der Member den Gültigkeitsbereich verlässt. Dies würde Speicher auf dem Heap zuweisen, aber sicher sein und verhindern, dass Sie den Speicher freigeben müssen. Dies funktioniert jedoch nur in C ++. Wenn Sie nur ein einfaches C verwenden, funktioniert dieser Ansatz nicht.

Wenn Sie versuchen, aus anderen Gründen auf dem Stack zu reservieren (normalerweise Leistung, da die Stackzuweisungen sehr, sehr schnell sind), würde ich _malloca empfehlen und mit der Tatsache leben, dass Sie _freea auf Ihren Werten aufrufen müssen .

    
Reed Copsey 09.04.2009, 16:06
quelle
3

Eine weitere Sache, die Sie beachten sollten, ist die Verwendung einer RAII-Klasse zur Verwaltung der Zuweisung - das ist natürlich nur nützlich, wenn Ihr Makro (oder was auch immer) auf C ++ beschränkt sein kann.

Wenn Sie den Heap aus Performance-Gründen vermeiden möchten, werfen Sie einen Blick auf die Techniken, die von Matthew Wilsons Template-Klasse auto_buffer<> verwendet werden ( http://www.stlsoft.org/doc-1.9/classstlsoft_1_1auto__buffer.html ). Dies wird auf dem Stapel zugewiesen, es sei denn, Ihre Anforderung für die Laufzeitgröße überschreitet eine zum Zeitpunkt des Compilers angegebene Größe. So erhalten Sie für die meisten Zuordnungen die Geschwindigkeit ohne Heapzuweisung (wenn Sie die Vorlage richtig dimensionieren) diese Größe.

Da STLsoft eine Menge Probleme mit Portabilitätsproblemen hat, sollten Sie sich eine einfachere Version von auto_buffer<> ansehen, die in Wilsons Buch " Imperfect C ++ ".

Ich fand es ziemlich praktisch in einem eingebetteten Projekt.

    
Michael Burr 09.04.2009 17:10
quelle
1

Um Speicher auf dem Stack zuzuordnen, deklarieren Sie einfach eine Variable des entsprechenden Typs und der richtigen Größe.

    
Mitch Wheat 09.04.2009 16:01
quelle
1

Ich habe das schon einmal beantwortet, aber ich hatte etwas Grundlegendes verpasst, was bedeutete, dass es nur im Debug-Modus funktionierte. Ich habe den Aufruf von _malloca in den Konstruktor einer Klasse verschoben, die sich automatisch freigeben würde.

Im Debug ist das in Ordnung, da es immer auf dem Heap allokiert wird. Bei der Freigabe wird es jedoch auf dem Stapel zugeordnet, und nach der Rückkehr vom Konstruktor wurde der Stapelzeiger zurückgesetzt und der Speicher verloren.

Ich ging zurück und wählte einen anderen Ansatz, was zu einer Kombination aus der Verwendung eines Makros (eurgh) führte, um den Speicher zuzuordnen und ein Objekt zu instanziieren, das _freea automatisch auf diesem Speicher aufruft. Da es sich um ein Makro handelt, wird es im selben Stapelrahmen zugewiesen und funktioniert daher im Freigabemodus. Es ist genauso praktisch wie meine Klasse, aber etwas weniger schön zu benutzen.

Ich habe Folgendes getan:

%Vor%

Auf diese Weise kann ich mithilfe des folgenden Makroaufrufs reservieren, und es wird freigegeben, wenn die instanziierte Klasse den Gültigkeitsbereich verlässt:

%Vor%

Ich entschuldige mich dafür, etwas veröffentlicht zu haben, das eindeutig falsch war!

    
Darren Sandford 22.08.2013 10:54
quelle
0

Wenn es Ihr Anliegen ist, den temporären Speicher freizugeben, und Sie alles über Dinge wie Smart-Pointer wissen, dann verwenden Sie ein ähnliches Muster, bei dem Speicher freigegeben wird, wenn er den Gültigkeitsbereich verlässt.

%Vor%     
Andrew Grant 09.04.2009 16:58
quelle
0
___ answer735103 ___

Eine weitere Sache, die Sie beachten sollten, ist die Verwendung einer RAII-Klasse zur Verwaltung der Zuweisung - das ist natürlich nur nützlich, wenn Ihr Makro (oder was auch immer) auf C ++ beschränkt sein kann.

Wenn Sie den Heap aus Performance-Gründen vermeiden möchten, werfen Sie einen Blick auf die Techniken, die von Matthew Wilsons Template-Klasse _malloca() verwendet werden ( _freea() ). Dies wird auf dem Stapel zugewiesen, es sei denn, Ihre Anforderung für die Laufzeitgröße überschreitet eine zum Zeitpunkt des Compilers angegebene Größe. So erhalten Sie für die meisten Zuordnungen die Geschwindigkeit ohne Heapzuweisung (wenn Sie die Vorlage richtig dimensionieren) diese Größe.

Da STLsoft eine Menge Probleme mit Portabilitätsproblemen hat, sollten Sie sich eine einfachere Version von _malloca() ansehen, die in Wilsons Buch " Imperfect C ++ ".

Ich fand es ziemlich praktisch in einem eingebetteten Projekt.

    
___ qstntxt ___

Ich entwickle unter Windows mit DevStudio, in C / C ++ unmanaged.

Ich möchte etwas Speicher auf dem Stack statt des Heaps reservieren, weil ich nicht mit der manuellen Freigabe dieses Speichers fertig werden will (ich kenne Smart-Pointer und all diese Dinge. Ich habe einen sehr spezifischen Fall von Speicher Zuordnung, mit der ich mich auseinandersetzen muss), ähnlich der Verwendung von A2W () - und W2A () - Makros.

_alloca macht das, aber es ist veraltet. Es wird empfohlen stattdessen malloca zu verwenden. Aber _malloca Dokumentation sagt, dass ein Anruf zu ___ freea ist obligatorisch für jeden Anruf zu _malloca. Es schlägt dann meinen Zweck, _malloca zu verwenden, ich werde stattdessen malloc oder neu verwenden.

Weiß jemand, ob ich durchkommen kann, wenn ich _freea nicht ohne Leckage anrufe und was die Auswirkungen innerlich sind?

Andernfalls werde ich am Ende nur die veraltete _alloca-Funktion verwenden.

    
___ answer734878 ___

Es ist immer wichtig, _freea nach jedem Aufruf von _malloca aufzurufen.

_malloca ist wie _alloca, fügt jedoch zusätzliche Sicherheitsüberprüfungen und Verbesserungen für Ihren Schutz hinzu. Daher ist es möglich, dass _malloca auf dem Heap anstelle des Stacks zugewiesen wird. Wenn dies geschieht und Sie _freea nicht aufrufen, erhalten Sie einen Speicherverlust.

Im Debug-Modus wird _malloca IMMER auf dem Heap allokiert, sollte also ebenfalls freigegeben werden.

Suchen Sie nach _ALLOCA_S_THRESHOLD, um zu erfahren, wie die Schwellenwerte funktionieren und warum _malloca anstelle von _alloca vorhanden ist, und das sollte sinnvoll sein.

Bearbeiten:

Es gibt Kommentare, die darauf hindeuten, dass die Person nur auf dem Heap allokiert und intelligente Zeiger usw. verwendet.

Stackzuweisungen, die _malloca Ihnen zur Verfügung stellt, haben Vorteile. Es gibt also Gründe, dies zu tun. _alloca wird auf die gleiche Weise funktionieren, aber es ist viel wahrscheinlicher, dass es zu einem Stack-Überlauf oder anderen Problemen kommt, und bietet leider keine schönen Ausnahmen, sondern neigt eher dazu, den Prozess einfach abzubrechen. _malloca ist in dieser Hinsicht viel sicherer und schützt Sie, aber die Kosten sind, dass Sie noch Ihren Speicher mit _freea freigeben müssen, da es möglich ist (aber im Freigabemodus unwahrscheinlich), dass _malloca beschließen wird, auf dem Heap anstelle des Stapels zuzuweisen.

Wenn Sie nur vermeiden möchten, dass Sie Speicher freigeben müssen, würde ich Ihnen einen intelligenten Zeiger empfehlen, der die Speicherfreigabe für Sie übernimmt, wenn der Member den Gültigkeitsbereich verlässt. Dies würde Speicher auf dem Heap zuweisen, aber sicher sein und verhindern, dass Sie den Speicher freigeben müssen. Dies funktioniert jedoch nur in C ++. Wenn Sie nur ein einfaches C verwenden, funktioniert dieser Ansatz nicht.

Wenn Sie versuchen, aus anderen Gründen auf dem Stack zu reservieren (normalerweise Leistung, da die Stackzuweisungen sehr, sehr schnell sind), würde ich _malloca empfehlen und mit der Tatsache leben, dass Sie _freea auf Ihren Werten aufrufen müssen .

    
___ qstnhdr ___ Aufruf an _freea wirklich notwendig? ___ answer18378471 ___

Ich habe das schon einmal beantwortet, aber ich hatte etwas Grundlegendes verpasst, was bedeutete, dass es nur im Debug-Modus funktionierte. Ich habe den Aufruf von _malloca in den Konstruktor einer Klasse verschoben, die sich automatisch freigeben würde.

Im Debug ist das in Ordnung, da es immer auf dem Heap allokiert wird. Bei der Freigabe wird es jedoch auf dem Stapel zugeordnet, und nach der Rückkehr vom Konstruktor wurde der Stapelzeiger zurückgesetzt und der Speicher verloren.

Ich ging zurück und wählte einen anderen Ansatz, was zu einer Kombination aus der Verwendung eines Makros (eurgh) führte, um den Speicher zuzuordnen und ein Objekt zu instanziieren, das _freea automatisch auf diesem Speicher aufruft. Da es sich um ein Makro handelt, wird es im selben Stapelrahmen zugewiesen und funktioniert daher im Freigabemodus. Es ist genauso praktisch wie meine Klasse, aber etwas weniger schön zu benutzen.

Ich habe Folgendes getan:

%Vor%

Auf diese Weise kann ich mithilfe des folgenden Makroaufrufs reservieren, und es wird freigegeben, wenn die instanziierte Klasse den Gültigkeitsbereich verlässt:

%Vor%

Ich entschuldige mich dafür, etwas veröffentlicht zu haben, das eindeutig falsch war!

    
___ answer735071 ___

Wenn es Ihr Anliegen ist, den temporären Speicher freizugeben, und Sie alles über Dinge wie Smart-Pointer wissen, dann verwenden Sie ein ähnliches Muster, bei dem Speicher freigegeben wird, wenn er den Gültigkeitsbereich verlässt.

%Vor%     
___ tag123windows ___ ALLGEMEINER WINDOWS-SUPPORT IST OFF-TOPIC. Support-Fragen können unter https://superuser.com gestellt werden. Windows ist ein von Microsoft entwickeltes Betriebssystem. Verwenden Sie dieses Tag nur, wenn sich Ihre Frage auf die Verwendung von Windows-APIs oder Windows-spezifischem Verhalten in Bezug auf Ihren Code bezieht, nicht nur, weil Sie Ihren Code unter Windows ausführen. ___ tag123stack ___ Ein Stapel ist ein LIFO-abstrakter Datentyp und eine letzte Datenstruktur. Eine häufige Verwendung von Stapeln besteht darin, Unterroutinenargumente zu speichern und Adressen zurückzugeben. ___ tag123memorymanagement ___ Prozess des dynamischen Zuweisens und Freigebens von Teilen des physischen Speichers, um auf Programmanforderungen mit, wenn möglich, Fairness und ohne Verhungern unter den Anforderern zu antworten. ___ answer734862 ___

Um Speicher auf dem Stack zuzuordnen, deklarieren Sie einfach eine Variable des entsprechenden Typs und der richtigen Größe.

    
___ antwort43836936 ___

Wenn Sie _freea() verwenden, müssen Sie _alloca() aufrufen, um Speicherverlust zu vermeiden, da _freea() die Zuweisung entweder auf Stack oder Heap ausführen kann. Wenn der angegebene Wert für overall_ALLOCA_S_THRESHOLD den angegebenen Wert überschreitet, greift er auf den Heap zu. Daher ist es sicherer, %code% aufzurufen, was nichts bewirkt, wenn die Zuordnung auf dem Stack erfolgt.

Wenn Sie %code% verwenden, scheint es ab heute veraltet zu sein; Es ist nicht notwendig, %code% aufzurufen, da die Zuweisung auf dem Stack erfolgt.

    
___
anurag-jain 07.05.2017 21:31
quelle