メモリについてのメモ。
メモリは1番地ごとに1byteの空間をもっている。
0x12345678 -> 0xaa
0x12345679 -> 0xaa
0x1234567a -> 0xaa
0x1234567b -> 0xaa
4byte単位で区切った際のひとつひとつを「1語」「1ワード」と言ったりする。
0x12345678 -> 0xaabbccdd
0x1234567c -> 0xaabbccdd
0x12345680 -> 0xaabbccdd
0x12345684 -> 0xaabbccdd
0x12345688 -> 0xaabbccdd
0x1234568c -> 0xaabbccdd
0x12345690 -> 0xaabbccdd
型について
- char -> BYTE型:1byte
- short -> WORD型:2byte
- int -> DWORD型:4byte
配列について
char array[] = {‘a’, ‘b’, ‘c’, 0};
0x12345678 -> 'a'
0x12345679 -> 'b'
0x1234567a -> 'c'
0x1234567b -> 0x00
- array = 0x12345678
- array[0] = *(array + 1*0) = *(0x12345678 + 0) = “a”
- array[1] = *(array + 1*1) = *(0x12345678 + 1) = “b”
- array[3] = *(array + 1*3) = *(0x12345678 + 3) = 0x00
int array[] = {8, 255, 1024};
0x12345678 -> 0x00000008
0x1234567c -> 0x000000ff
0x12345680 -> 0x00000400
- array = 0x12345678
- array[0] = *(array + 4*0) = *(0x12345678 + 0) = 0x00000008
- array[1] = *(array + 4*1) = *(0x12345678 + 4) = 0x000000ff
- array[2] = *(array + 4*2) = *(0x12345678 + 8) = 0x00000400
連続宣言時の挙動
- char arrayA [ ] = {‘a’, ‘b’, ‘c’};
- char arrayB [ ] = {’d', ‘e’, ‘f’};
- arrayA[0]: *0x12345678 = ‘a’
- arrayA[1]: *0x12345679 = ‘b’
- arrayA[2]: *0x1234567a = ‘c’
- arrayB[0]: *0x1234567b = ’d'
- arrayB[1]: *0x1234567c = ‘e’
- arrayB[2]: *0x1234567d = ‘f’
実はこんなこともできる
arrayA: 0x12345678
arrayB: 0x1234567b
arrayB[0]: *(arrayB + 1*0) = *(0x1234567b + 0) = *0x1234567b = 'd'
arrayA[3]: *(arrayA + 1*3) = *(0x12345678 + 3) = *0x1234567b = 'd'
arrayA[4]: *0x1234567c = 'e'
arrayA[5]: *0x1234567d = 'f'
実際に配列宣言時のメモリの中身を覗くプログラムをC言語で書いてみた
#include <stdio.h>
int main(void){
int hoge[] = {111,222,333,444};
int fuga[] = {555,666,777,888};
printf("[+] int hoge[] = {111,222,333,444};\n");
printf("[+] int fuga[] = {555,666,777,888};\n\n");
printf("hoge : %p\n", hoge);
printf("fuga : %p\n", fuga);
printf("hoge[0]: %d\n", hoge[0]);
printf("hoge[1]: %d\n", hoge[1]);
printf("hoge[2]: %d\n", hoge[2]);
printf("hoge[3]: %d\n", hoge[3]);
printf("fuga[0]: %d\n", fuga[0]);
printf("fuga[1]: %d\n", fuga[1]);
printf("fuga[2]: %d\n", fuga[2]);
printf("fuga[3]: %d\n\n", fuga[3]);
printf("hoge : %p -> %d\n", hoge, hoge[0]);
printf("&hoge[0]: %p -> %d\n", &hoge[0], hoge[0]);
printf("fuga : %p -> %d\n", fuga, fuga[0]);
printf("&fuga[0]: %p -> %d\n\n", &fuga[0], fuga[0]);
printf("&hoge[0]: %p -> %d (0x%08x)\n", &hoge[0], hoge[0], hoge[0]);
printf("&hoge[1]: %p -> %d (0x%08x)\n", &hoge[1], hoge[1], hoge[1]);
printf("&hoge[2]: %p -> %d (0x%08x)\n", &hoge[2], hoge[2], hoge[2]);
printf("&hoge[3]: %p -> %d (0x%08x)\n\n", &hoge[3], hoge[3], hoge[3]);
printf("&hoge[4]: %p -> %d (0x%08x)\n", &hoge[4], hoge[4], hoge[4]);
printf("&hoge[5]: %p -> %d (0x%08x)\n", &hoge[5], hoge[5], hoge[5]);
printf("&hoge[6]: %p -> %d (0x%08x)\n\n", &hoge[6], hoge[6], hoge[6]);
printf("&fuga[0]: %p -> %d (0x%08x)\n", &fuga[0], fuga[0], fuga[0]);
printf("&fuga[1]: %p -> %d (0x%08x)\n", &fuga[1], fuga[1], fuga[1]);
printf("&fuga[2]: %p -> %d (0x%08x)\n", &fuga[2], fuga[2], fuga[2]);
return 0;
}
$ gcc -o memory memory.c
$ ./memory
/* ######### 出力結果 ########## */
[+] int hoge[] = {111,222,333,444};
[+] int fuga[] = {555,666,777,888};
hoge : 0x7fff2df76c10
fuga : 0x7fff2df76c20
hoge[0]: 111
hoge[1]: 222
hoge[2]: 333
hoge[3]: 444
fuga[0]: 555
fuga[1]: 666
fuga[2]: 777
fuga[3]: 888
hoge : 0x7fff2df76c10 -> 111
&hoge[0]: 0x7fff2df76c10 -> 111
fuga : 0x7fff2df76c20 -> 555
&fuga[0]: 0x7fff2df76c20 -> 555
&hoge[0]: 0x7fff2df76c10 -> 111 (0x0000006f)
&hoge[1]: 0x7fff2df76c14 -> 222 (0x000000de)
&hoge[2]: 0x7fff2df76c18 -> 333 (0x0000014d)
&hoge[3]: 0x7fff2df76c1c -> 444 (0x000001bc)
&hoge[4]: 0x7fff2df76c20 -> 555 (0x0000022b)
&hoge[5]: 0x7fff2df76c24 -> 666 (0x0000029a)
&hoge[6]: 0x7fff2df76c28 -> 777 (0x00000309)
&fuga[0]: 0x7fff2df76c20 -> 555 (0x0000022b)
&fuga[1]: 0x7fff2df76c24 -> 666 (0x0000029a)
&fuga[2]: 0x7fff2df76c28 -> 777 (0x00000309)
/* ############################# */