Visual C とアサートを指定したので、デバッグ ビルドを使用できると仮定します。その場合、この特定のコンパイラがメモリ チェックのために配置するフェンスポストを利用できます。
#define IS_POINTER_TO_STACK(vp) (*((int*)(vp)-1)==0xCCCCCCCC)
デバッグビルドでは、これらすべてのケースで正しく機能しました:
#define ASSERT(v) printf("assert: %d\n", v); //so it doesn't really quit
int g_n = 0;
void test_indirectly(void* vp) {
ASSERT(IS_POINTER_TO_STACK(vp));
}
void F() {
int *pA = &g_n;
ASSERT(IS_POINTER_TO_STACK(pA)); //0
int i = 0;
int j = 0;
int *pB = &i;
ASSERT(IS_POINTER_TO_STACK(pB)); //1
ASSERT(IS_POINTER_TO_STACK(&j)); //1
int *pC = (int*)malloc(sizeof(int));
ASSERT(IS_POINTER_TO_STACK(pC)); //0
free(pC);
ASSERT(IS_POINTER_TO_STACK(pC)); //0
pC = new int;
ASSERT(IS_POINTER_TO_STACK(pC)); //0
delete pC;
char* s = "HelloSO";
char w[6];
ASSERT(IS_POINTER_TO_STACK("CONSTANT")); //0
ASSERT(IS_POINTER_TO_STACK(s)); //0
ASSERT(IS_POINTER_TO_STACK(&w[0])); //1
test_indirectly(&s); //1
int* pD; //uninit
ASSERT(IS_POINTER_TO_STACK(pD)); //runtime error check
}
(ただし、メモリが初期化されていないために実行時エラーが発生した最後のエラーを除きますが、それでもポインタを検証する目的には役立ちます。)
これはデバッグ ビルドでのみ機能します。リリース ビルドでは、すべてのビルドで false が報告されます。