-1

このコードは、スタックに割り当てられた変数への無効な参照を返しますか? または何:

void *f(size_t sz) {
    return alloca(sz);
}

それとも、alloca の実装/コンパイラ サポートによって処理される特殊なケースf(alloca(size), alloca(size))ですか?

4

6 に答える 6

5

allocaのスタックフレームにスペースを割り当てますf。関数が戻ると、それを使って有用なことは何もできなくなります(もう「予約」されていません)。

alloca()関数は、呼び出し元のスタックフレームにサイズバイトのスペースを割り当てます。この一時スペースは、alloca()を呼び出した関数が呼び出し元に戻ると自動的に解放されます

于 2011-08-13T06:27:52.243 に答える
1

Linuxのマニュアルページによると:

このalloca()関数は、呼び出し元のスタックフレームにスペースを割り当て、割り当てられたブロックへのポインターを返します。この一時スペースは、呼び出された関数が戻るときに自動的に解放さalloca() れます。

つまり、によって返されたメモリにアクセスしようとすると、戻ったf()ときに解放されるため、未定義の動作が発生しf()ます。

于 2011-08-13T06:28:30.450 に答える
1

はい、コードは無効なポインタを返します。alloca呼び出しを関数にラップすることはできません。ラップする必要がある場合allocaは、マクロラッパーに制限されます。

于 2011-08-13T06:33:09.130 に答える
0

他の人が言っているように、それは解放されるでしょう、そして私はあなたがどのように振る舞いを変えることができるか本当にわかりません。allocaがamd-64でどのようにコンパイルされるかを見ると:

pushq   %rbp
movq    %rsp, %rbp
subq    $144, %rsp
movq    %rsp, %rax
addq    $15, %rax
shrq    $4, %rax
salq    $4, %rax
leave
ret

分かりますか

1)Allocaは実際には関数呼び出しではありません(あなたが言ったように、スタックを別の方法で処理する必要があるためです!)

2)スタックポインタに対してallocaが行うことはすべて、rbp上書き時に関数の最後で壊れるだけです。rsp

それで、あなたはあなたが尋ねる振る舞いを(アセンブリを書かずに)得ることができますか?それは難しい質問で、私にはわかりませんが、おそらくそうではないようです。

于 2011-08-13T06:36:40.757 に答える
0

私は alloca を自分で使用したことはありませんが、ここで「インラインの問題」について読み ました。

「最も記憶に残るバグの 1 つ...」という回答は非常に興味深いものです。

したがって、関数がスコープ外になるとメモリが確実に解放されるというわけではありません。

于 2011-09-02T05:59:50.383 に答える