web-dev-qa-db-ja.com

関数呼び出し中のCでのメモリ割り当て

Cで書かれたコードでメモリがどのように割り当てられるかについて、本当に基本的な質問があります。

私がこのようなものを持っているとしましょう:

int pointless(int a); 
int main(){
     int num1,num2;
     num1=1;
     num2=pointless(num1);
     return 0;
}
int pointless(int a)
{             
     return a;
}

私が知りたいのは、pointless()関数内で何が起こっているかです。 main()で、呼び出された関数に渡される「num1」変数にすでに2バイトを割り当てています。この時点で、無意味な関数にジャンプすると、もう一度「a」変数用にスペースが割り当てられますか?それとも、関数がメモリ内の変数の値にアクセスできるようにするだけですか? (pointless()関数の内部で一時的に変数の割り当てが重複している場合、今書いている問題が発生します。)

ありがとう!

3
user228747

stackのintにスペースを割り当て、 'num1'の値をスタックにコピーし、メソッドを呼び出して、値を返します、その時点でスタックがポップされます。基本的に、関数で使用するために、スタックに 'num1'のcopyがあります。

代わりにpointerまたはreferenceを 'num1'に渡した場合、次に、アドレスがスタックに置かれ、関数はそのアドレスを介して変数を修正します。したがって、値のコピーはなく、元の変数への参照が必要です。

ここに役立つ説明があります 何が起こっているのか(StackOverflowから)

5
Brian Agnew

C言語標準 は、関数パラメーターにメモリを割り当てる方法を要求せず、そのメモリの動作方法のみを要求します。これは、関数パラメーターにblockスコープ(関数本体の外には表示されない)があり、linkage(コード内の他の識別子が同じオブジェクトを参照しない)、および自動ストレージ期間(スペースは最初に割り当てられます)関数と関数の終了時に解放されます)。

正確なメモリ割り当て動作は、特定のプラットフォームの機能です1呼び出し規約 。たとえば、x86-64の場合、関数引数のスタックにはスペースが割り当てられません。代わりに、レジスタ(%rcx Windowsでは%rdi on * nix)。多くのRISCアーキテクチャ(MIPS、PowerPC、SPARC)も、単純な呼び出しではスタックではなくレジスタを介して引数を渡します。

さらに、プラットフォームによっては、スタックスペースを特定の境界に合わせる必要があります。スタックを介して単一の2バイトの引数を渡し、スタックポインターを4バイトのアドレスに揃える必要がある場合、スタックポインターは4バイト調整され、2バイトが割り当てられますが未使用のままになります。




  1. 「プラットフォーム」は、ハードウェアとオペレーティングシステムの組み合わせです。
2
John Bode