2016-06-16 7 views
2

このプログラムを作成するときにスタックがFILOセグメント(First In Last Out)であることを知っているので、以下のようにpassword_buffer変数の後にauth_flag変数が格納されていると思います。スタックに変数を格納する方法

私は、GDBでauth_flagとpassword_bufferの場所を確認した場合、私は確かにそのauth_flagを参照してください
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
int check_authentication(char *password) { 
int auth_flag = 0; 
char password_buffer[16]; 
... 
} 

int main(int argc, char *argv[]) { 
.... 
} 

は28バイトでpassword_buffer後です:変数の宣言を反転した後

(gdb) x/s password_buffer 
0x7fffffffe3f0: "\001" 
(gdb) x/xw &auth_flag 
0x7fffffffe40c: 0x00000000 
(gdb) # now let's print how many bytes is auth_flag away from  password_buffer 
(gdb) print 0x7fffffffe40c - 0x7fffffffe3f0 
$3 = 28 
(gdb) # so auth_flag is 28 bytes after password_buffer 

、私はpassword_bufferが後に保存されていことを期待しますauth_flag:

int check_authentication(char *password) { 
char password_buffer[16]; 
int auth_flag = 0;  
... 
} 

しかし、これはgdbでの実験で同じ結果が出たため、何も起こりません。これはどのように可能ですか? password_bufferの前にauth_flagを置くべきではありませんか?

+0

再コンパイル時にプログラムが変更されたことはありますか?時にはプログラムの機能に影響を与えない変更があると、変更はコンパイラによって「最適化」されます。 – phormalitize

+1

[スタック上のローカル変数割り当ての順序]の可能な複製(http://stackoverflow.com/questions/1102049/order-of-local-variable-allocation-on-the-stack)。 –

答えて

7

変数が(通常は)スタックに置かれても、関数は実行されますが、コンパイラは任意の順序で自由に配置できます。通常、開発者は順序を気にする必要はありませんが、コンパイラはどの順序で最適であるべきかをよく知っています。

ご注文の場合は、structを使用することができ、コンパイラはこれらの注文を再注文しません。

また、私が正しく覚えていれば、Cの標準でもスタックが存在する必要はなく、変数はどこにでも置くことができます。

+2

あなたは正しい:C標準は文字通り何もスタックについて何も言わない。その言葉は標準のどこにも現れません。 「ヒープ」と同じです。 –

+0

スタック/スタックサイズはコンパイラとOS固有のため、私はこれを言っている、なぜなら私は人々がJavaのスタックサイズがCで大きくなっていると言っているから) – Michi

+1

"変数はどこにでもあることができる"。これは、最適化されたコードのローカル変数でよく見られます。スタックにはまったく割り当てられません(レジスタのみ)。 – dbrank0

関連する問題