0
int main()
{
    int *a; // a = 0x4053c6 (a random address)
    // this will cause the program to exit, and how do i know this memory can't be written ?
    *a = 5;
    return 0;
}

混乱している!つまり、このスニペットは常にプログラムをクラッシュさせるのでしょうか?そして、このプログラムが最初から最後まで実行できる場合はありますか?

4

2 に答える 2

0

コードはセグメンテーション違反/アクセス違反があり、オペレーティングシステムに応じてトラップまたはシグナルとして処理されます。あなたはそれを扱うことができるかもしれませんが、それはあなたが後で多くをすることができることはほとんどありません。(それを処理した後の通常の行動方針は優雅な出口です)。

ケースがあることを立証することに関しては、それを証明するのはかなり難しいでしょう。たとえば、初期化されていない変数をスタック上の特定のアドレスに設定する独自のコンパイラを使用できます(皮肉)。

aの値を疑似初期化する1つの方法は、関数を呼び出すことです。

void func(int k)
{
    int *a;
    int b = 0;
    if (k == 1) {
        a = &b;
    }
    *a = 5;
}

func(1)を数回試してから、func(2)を試すことができます。aとbが同じスタック領域を再利用し、失敗しない可能性があります。しかし、これもチャンスです。

于 2013-03-15T06:09:34.820 に答える
0

通常はクラッシュにつながりますが、保証されていません(変数は初期化されていないため、有効または無効の任意の値が含まれている可能性があります)。C ++例外でアクセス違反をキャッチすることはできませんが、コンパイラーはそれを行うための拡張機能を提供します。たとえば、Visual C ++では、SEH(構造化例外処理)を使用できます。

#include <Windows.h>
#include <iostream>

using namespace std;

int main()
{
    int* p = reinterpret_cast<int*>(0x00000100);

    __try
    {
        *p = 10;
    }
    __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
    {
        cout << "Access violation" << endl;
        return -1;
    }

    cout << *p << endl;
}
于 2013-03-15T06:13:11.317 に答える