このコードは、スタックに割り当てられた変数への無効な参照を返しますか?それとも何:それは次のようになりf(alloca(size), alloca(size))
などのallocaを実装/コンパイラのサポートによって処理された特殊なケースallocaポインタを返す
void *f(size_t sz) {
return alloca(sz);
}
をかありますか?
このコードは、スタックに割り当てられた変数への無効な参照を返しますか?それとも何:それは次のようになりf(alloca(size), alloca(size))
などのallocaを実装/コンパイラのサポートによって処理された特殊なケースallocaポインタを返す
void *f(size_t sz) {
return alloca(sz);
}
をかありますか?
alloca
は、スタックフレームのスペースをf
に割り当てます。関数が返ったら(それはもはや "予約されていません")、あなたはそれに役立つ何もできません。
alloca()関数は、呼び出し元のスタックフレーム のスペースのサイズバイトを割り当てます。この一時的なスペースは、にalloca()を呼び出した 関数が返されると自動的に解放され、になります。 Linux manual page 1として
:
alloca()
機能は 呼び出し元のスタックフレーム内の空間を割り当て、割り当てられたブロックへのポインタを返します。この一時的な スペースは、alloca()
という関数が呼び出されると自動的に解放されます。それはときf()
リターンを解放される手段として
、f()
によって返されたメモリにアクセスしようとすると、未定義の動作につながります。
はい、コードは無効なポインタを返します。 alloca
呼び出しを関数にラップすることはできません。 alloca
をラップする必要がある場合は、マクロラッパーに限定されます。
他の人が言っているように、それは解放され、どのように行動を変えることができないのか分かりません。あなたは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
のででしあなたは(アセンブリを書くことなく)尋ねる振る舞いを得ますか?それは難しい質問ですが、わかりませんが、おそらくそうではないようです。
私は自分自身ALLOCA使用したことがないが、私はここでは「インライン問題」について読む: Why is the use of alloca() not considered good practice?
答え「最も記憶に残るバグの一つ...」非常に興味深いです。
したがって、関数が有効範囲外になったときにメモリが確実に解放されるわけではありません。
この:
void *f() {
char pc4[4];
...
}
どちらもあなたが後者の場合には関数の外/使用PC4を返すことができず、あなたが最初のケースで同じ操作を行うことができます。
void *f() {
char* pc4 = alloca(4);
...
}
はまさにこれです。
あなたの質問とはちょっと違いますが、 'alloca'は常に無効なポインタを返すことがあります。本当に何もできません。 'alloca'を使ったコードは間違ったコードであり、深刻な脆弱性の影響を受けやすいでしょう。 –
に:この "コードを使用してallocaはほぼ確実に間違ったコードです" "ナイフの任意の使用は間違っている"とかそのようなものです。 allocaは、応答的かつ目的に応じて使用すると強力な機能です。 –