1

このコードは完全に有効ですか?ここでポインタを返すことで、未定義の動作が発生することはありませんか?

#include <iostream>
using namespace std;

int* lab(int* i) {
        int k=9;
        i=&k;
        return i;
}

int main(void) {
        int* i=0;
        cout << *lab(i) << endl;
        return 0;
}

編集:どのように有効なコードがどのように見えることができますか?

4

3 に答える 3

7

いいえ。それは無効です。ローカル変数へのポインタを返すことはできません。lab()出口kが存在せず、出口へのポインタを逆参照すると、未定義の動作が発生します。

Think about where k is stored. Automatic variables that you take the address of are stored on the stack. The stack grows when functions are entered and shrinks when they exit. When lab() returns the stack space that was allocated to k is reclaimed and can be reused by the runtime, possibly for other local variables in some other functions.

There are a couple of ways to fix this. The easiest is to have the caller provide a location to store the value in rather than having lab() try to find space. This eliminates the problem of k being deallocated when lab() returns.

int* lab(int* i) {
    *i = 9;
    return i;
}

int main(void) {
    int k;
    cout << *lab(&k) << endl;
    return 0;
}

Another way is to declare k as static. Static variables are stored in permanent storage somewhere, not on the stack, so their addresses remain valid throughout the lifetime of the program.

int* lab() {
    static int k=9;
    return &k;
}

And yet another way is to allocate memory on the heap using new.

int* lab() {
    int* i = new int;
    *i = 9;
    return i;
}

int main(void) {
    int* i = lab();
    cout << *i << endl;
    delete i;
    return 0;
}
于 2013-01-31T04:26:22.870 に答える
1

int kは、関数が戻るときに削除されます。したがって、メモリの未割り当て部分を指します。エラー

于 2013-01-31T04:26:01.793 に答える
1

いいえ、無効です。 lab変数ローカル変数へのポインタを返します。そのポインタは、一度lab存在すると無効になります。アクセスは未定義の動作です。

于 2013-01-31T04:26:03.507 に答える