2015-02-24 5 views
23

Meine Frage ist ziemlich einfach und direkt: wenn ich z. 1MB RAM, die dem Stack des Programms zugewiesen sind, kann ich die Adressen des Anfangs und des Endes oder des Anfangs und der Länge erhalten?Kann ich die Grenzen des Stapels in C/C++ bekommen?

Ich bin mit Visual Studio 2013

+3

Ich denke, es ist OS-spezifische, so kann ich Ihnen nicht helfen, aber ich bin in der Antwort interessiert. .. –

+3

http://en.wikipedia.org/wiki/Win32_Thread_Information_Block –

+0

Ich denke, Sie sind nicht wirklich an etwas interessiert, aber freie Stapel links, oder? – Deduplicator

Antwort

30

Sie sollten Ihre Annahmen über Stack Layout hinterfragen.

Vielleicht the stack doesn't have just one top and bottom

Vielleicht it has no fixed bottom at all

Offensichtlich gibt es keine portable Möglichkeit Konzepte zur Abfrage, die nicht tragbar sind.

Von Visual C++ können Sie jedoch die Win32-API je nach Windows-Version verwenden.

auf Windows 8 ist es sehr einfach, rufen Sie einfach GetCurrentThreadStackLimits

Frühere Versionen müssen VirtualQueryEx verwenden und die Ergebnisse etwas zu verarbeiten. Es ist einfach, eine Adresse im Stack zu finden, verwenden Sie einfach & für eine lokale Variable. Dann müssen Sie die Grenzen der reservierten Region finden, die diese Adresse enthält. Joe Duffy hat geschrieben a blog post showing the details of finding the bottom address of the stack

+0

Als [Thread Stack Size] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms686774%28v=vs.85%29 .aspx) sagt, * Standard * Anfangs- und Reservegrößen können aus dem PE-Header abgerufen werden (es gibt nicht * den Header * des Moduls an). –

+0

@ivan_pozdeev: Das ist nur die Stapelgröße für den Hauptthread, obwohl sie auch als Standard für später erstellte Threads dient, ihre Größe wird dynamisch festgelegt. Und natürlich ist es der PE-Header des ausführbaren Bildes, der mit 'GetModuleHandle (NULL) 'übereinstimmt. –

+0

Ihre Annahme, dass Visual C++ == Win32 wird nicht so lange klingen (http://blogs.msdn.com/b/vcblog/archive/2014/11/12/cross-platform-mobile-development -with-visual-c.aspx) –

9

GetCurrentThreadStackLimits scheint zu tun, was Sie suchen, bekommen die untere/obere Grenze des Stapels in Zeigeradressen:

ULONG_PTR lowLimit; 
ULONG_PTR highLimit; 
GetCurrentThreadStackLimits(&lowLimit, &highLimit); 

wie es aussieht, ist nur auf Windows 8 und Server 2012 obwohl.

Überprüfen Sie die MSDN

0

Unter Windows vor 8 implementieren GetCurrentThreadStackLimits() selbst:

#include <windows.h> 
#if _WIN32_WINNT < 0x0602 
VOID WINAPI GetCurrentThreadStackLimits(LPVOID *StackLimit, LPVOID *StackBase) 
{ 
    NT_TIB *tib = (NT_TIB *) NtCurrentTeb(); 
    *StackLimit = tib->StackLimit; 
    *StackBase = tib->StackBase; 
} 
#endif 
+0

Aus dem Artikel von Joe Duffy, den ich in meiner Antwort verlinkt habe: * Leider wird das 'StackLimit' nur aktualisiert, wenn Sie Seiten auf dem Stack berühren, und somit ** ist es kein zuverlässiger Weg herauszufinden, wie viel nicht festgeschriebener Stack übrig ist * *. Die CLR verwendet 'kernel32! VirtualAlloc', um die Seiten zu committen, nicht indem die Guard-Seite tatsächlich verschoben wird, also wird **' StackLimit' nicht wie erwartet aktualisiert. *** Aber wenn Sie die Kommentare unter der Frage lesen, bevor Sie antworten , Sie hätten bereits gewusst, dass die TIB nicht die benötigten Informationen enthält. –

Verwandte Themen