お世話になります。
C/C++において配列名はその配列の先頭アドレスを示しますが、
その配列名がこの先頭アドレスを示しているという情報は、
メモリのどこに配置されているものなのでしょうか?
例えば、1次元配列 testA[5]、2次元配列のtestB[3][2]の場合ですと、
testAが先頭アドレス、
testBが先頭アドレス、testB[0]、testB[1]、testB[2]が各[0][0]のアドレスを示すと思いますが、
その情報が実行ファイル内のどこにどのような情報として保管され、
及び実行中にはメモリのどこにどう展開されるのかご存知の方がおりましたがご教授頂けますと幸いです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
C
1#include <stdio.h> 2 3void f(int *); 4void g(int [][2]); 5 6int testA[5]; 7int testB[3][2]; 8 9int main(void) 10{ 11 int a[5]; 12 int b[3][2]; 13 f(testA); 14 g(testB); 15 f(a); 16 g(b); 17}
これを gcc (Ubuntu 9.3.0-10ubuntu2) 9.3.0 でコンパイルすると、
次のようなコードができました。
main: endbr64 subq $72, %rsp leaq testA(%rip), %rdi # testA movq %fs:40, %rax movq %rax, 56(%rsp) xorl %eax, %eax call f@PLT leaq testB(%rip), %rdi # testB call g@PLT movq %rsp, %rdi # a call f@PLT leaq 32(%rsp), %rdi # b call g@PLT movq 56(%rsp), %rax xorq %fs:40, %rax jne .L5 xorl %eax, %eax addq $72, %rsp ret
静的な変数 testA や testB は即値ではなく、%rip(インストラクションポインタ、
すなわちプログラムカウンタ)にオフセットを加えたアドレスで参照しています。
自動変数 a や b は、%rsp(スタックポインタ) にオフセットを加えたアドレスで
参照していました。ただし、a はオフセット0 なので、%rsp の値そのものです。
いずれにせよ、配列の「アドレス」は、メモリ上にデータとして配置されているもの
ではなく、コード中にオフセットという値で保持されていることが分かりました。
ただし、これは特定のコンパイラに依存することで、他のコンパイラでは
これとは異なるやり方でアドレスを持っているかもしれません。
Visual C++ の 32ビット版は、静的変数は即値、自動変数は EBP(ベースポインタ、
すなわちフレームポインタ) にオフセットだったと思います。
また、
testB[0] は testB[0][0] のアドレスに変換されますが、
testB[1] は testB[1][0] のアドレスに、そして、
testB[2] は testB[2][0] のアドレスに変換されます。
追記
Visual C++ の 32ビット版で -FAオプションでコンパイルすると、
_DATA SEGMENT COMM _testA:DWORD:05H COMM _testB:DWORD:06H _DATA ENDS PUBLIC _main EXTRN _f:PROC EXTRN _g:PROC EXTRN @__security_check_cookie@4:PROC EXTRN ___security_cookie:DWORD ; Function compile flags: /Odtp _TEXT SEGMENT _b$ = -48 ; size = 24 _a$ = -24 ; size = 20 __$ArrayPad$ = -4 ; size = 4 _main PROC ; File c:\tmp\c\a.c ; Line 10 push ebp mov ebp, esp sub esp, 48 ; 00000030H mov eax, DWORD PTR ___security_cookie xor eax, ebp mov DWORD PTR __$ArrayPad$[ebp], eax ; Line 13 push OFFSET _testA call _f add esp, 4 ; Line 14 push OFFSET _testB call _g add esp, 4 ; Line 15 lea eax, DWORD PTR _a$[ebp] push eax call _f add esp, 4 ; Line 16 lea ecx, DWORD PTR _b$[ebp] push ecx call _g add esp, 4 ; Line 17 xor eax, eax mov ecx, DWORD PTR __$ArrayPad$[ebp] xor ecx, ebp call @__security_check_cookie@4 mov esp, ebp pop ebp ret 0 _main ENDP _TEXT ENDS END
投稿2020/06/21 18:14
編集2020/06/22 01:23総合スコア8224
0
その配列名がこの先頭アドレスを示しているという情報は、
メモリのどこに配置されているものなのでしょうか?
即値としてコード内に埋め込まれます。データメモリ側で持つものではありません。
投稿2020/06/19 05:20
総合スコア146018
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2020/06/19 06:51
2020/06/19 06:52
退会済みユーザー
2020/06/19 06:57
退会済みユーザー
2020/06/19 08:13
2020/06/19 08:35 編集
退会済みユーザー
2020/06/19 17:35
退会済みユーザー
2020/06/21 13:19
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2020/06/22 01:17