C/C++では変数はいくつかのメモリ領域に確保されますが、ローカル変数の多くはスタックに確保されます。このスタックの情報、特に現在のスレッドのスタック情報を取得するにはWin32 APIのGetCurrentThreadStackLimits
関数が利用できます。
void GetCurrentThreadStackLimits(
PULONG_PTR LowLimit,
PULONG_PTR HighLimit
);
GetCurrentThreadStackLimits function (processthreadsapi.h) - Win32 apps | Microsoft Docs
この関数はスタックのアドレス下限LowLimit
と上限HighLimit
を返すので、その差HighLimit - LowLimit
からサイズが得られます。これをC++&STLで実装したコードを以下に示します。
// Win32 APIで現在のスレッドのスタックのアドレス上限・下限とサイズを取得する。
//
# include <iostream>
# include <iomanip>
# define STRICT
# define NOMINMAX
# include <Windows.h>
int main()
{
// UNICODEの有効化
// locale::ctypeは数値出力時のカンマ非表示に必要
std::wcout.imbue(std::locale("", std::locale::ctype));
ULONG_PTR lowLimit, highLimit;
GetCurrentThreadStackLimits(&lowLimit, &highLimit);
auto size = highLimit - lowLimit;
std::wcout << L"スタックのアドレス下限:0x" << std::setw(16) << std::setfill(L'0') << std::hex << lowLimit << std::endl;
std::wcout << L"スタックのアドレス上限:0x" << std::setw(16) << std::setfill(L'0') << std::hex << highLimit << std::endl;
std::wcout << L"スタックのサイズ:0x" << std::setw(16) << std::setfill(L'0') << std::hex << size << L"(" << std::dec << size << L")" << std::endl;
int a = 0;
ULONG_PTR pa = reinterpret_cast<ULONG_PTR>(&a);
std::wcout << L"ローカル変数aのアドレス:0x" << std::setw(16) << std::setfill(L'0') << std::hex << pa << std::endl;
std::wcout << L"aがスタックに含まれる:" << std::boolalpha << (lowLimit <= pa && pa <= highLimit) << std::endl;
return 0;
}