5

初心者の質問かもしれませんが、関数がローカル変数へのポインターを受け入れないようにする方法は C/C++ にありますか?

次のコードを検討してください。

int* fun(void)
{
 int a;
 return &a;
}

コンパイラは、ポインターを返すことができないという警告を生成します。これを考慮してください:

int* g;

void save(int* a)
{
 g = a;
}

void bad(void)
{
 int a;
 save(&a);
}

これは警告なしでコンパイラを通過しますが、これは悪いことです。これが起こらないようにするための属性または何かがありますか? つまり、次のようなものです。

void save(int __this_pointer_must_not_be_local__ * a)
{
 g = a;
}

誰かが答えを知っている場合は、事前に感謝します。

4

2 に答える 2

2

デバッグ ヒープを使用したデバッグ ビルドには、少なくとも 1 つの方法があります (デフォルト)。

//d:\Program Files\Microsoft Visual Studio ?\VC\crt\src\dbgint.h
\#define nNoMansLandSize 4
typedef struct _CrtMemBlockHeader
{
    struct _CrtMemBlockHeader * pBlockHeaderNext;
    struct _CrtMemBlockHeader * pBlockHeaderPrev;
    char *                      szFileName;
    int                         nLine;
    size_t                      nDataSize;
    int                         nBlockUse;
    long                        lRequest;
    unsigned char               gap[nNoMansLandSize];
    /* followed by:
     *  unsigned char           data[nDataSize];
     *  unsigned char           anotherGap[nNoMansLandSize];
     */
} _CrtMemBlockHeader;
\#define pbData(pblock) ((unsigned char *)((_CrtMemBlockHeader *)pblock + 1))

ギャップで終わる割り当てヘッダーがあるため、ポインターの前に 0xFDFDFDFD が存在する可能性は高くありません-完全ではありませんが、役立つ場合があります...

if (\*((int\*)pointer-1) == 0xFDFDFD) { // stack pointer }
于 2012-09-10T10:41:42.377 に答える
0

いいえ、ヒープオブジェクトへのポインタからローカルへのポインタを区別するための信頼できるポータブルな方法はありません。これを宣言的に防ぐ方法もありません。

特定のシステムのメモリレイアウトに依存して、不特定の動作を呼び出すことによって実行時に機能するハックがあります(例についてはこの回答を参照してください)が、試してみることにした場合は、あなた自身で行ってください。

于 2012-06-09T10:54:07.810 に答える