Linux 2.6カーネルを搭載したDebianを使用しており、ヒープがとでどのように機能/動作するかを理解しようとしていmalloc()
ますfree()
。malloc()
アルゴリズムとヒープ構造を検索しようとしましたfree()
が、役立つものが見つかりませんでした。そして残念ながら、私はLinuxとメモリのしくみについてあまり知らず、とのソースコードを理解できませfree()
んmalloc()
。
これはサンプルコードです:
int main(int argc, char **argv)
{
char *a, *b, *c;
a = malloc(32);
b = malloc(32);
c = malloc(32);
strcpy(a, argv[1]);
strcpy(b, argv[2]);
strcpy(c, argv[3]);
free(c);
free(b);
free(a);
}
でgdb
、run AAAA BBBB CCCC
ヒープを調べることができます。これは、:の後のstrcpys
前の状態です。frees
(gdb) x/32x 0x804c000
0x804c000: 0x00000000 0x00000029 0x41414141 0x00000000
0x804c010: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029
0x804c030: 0x42424242 0x00000000 0x00000000 0x00000000
0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c050: 0x00000000 0x00000029 0x43434343 0x00000000
0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
char配列が非常によくわかります。次に、なぜ0x29(dec 41)があるのかを理解しようとしました。0x20(dec 32)または0x24(dec 36)のようなものを期待します。
- なぜmallocアルゴリズムはこのスペースを浪費するのですか?
- 0x29であるとどのように判断されますか?
- そして最後の0xf89は何を表していますか?
- プログラムは、割り当てられたものと無料のものをどのように追跡しますか?
特に、どのように機能するのかを理解したいと思いfree()
ます。3回の解放後、ヒープは次のようになります。
(gdb) x/32x 0x804c000
0x804c000: 0x00000000 0x00000029 0x0804c028 0x00000000
0x804c010: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c020: 0x00000000 0x00000000 0x00000000 0x00000029
0x804c030: 0x0804c050 0x00000000 0x00000000 0x00000000
0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c050: 0x00000000 0x00000029 0x00000000 0x00000000
0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
- char配列がこの特定のアドレスに置き換えられるのはなぜですか?
- freeが行う疑似コードとは何ですか?
この例を見てください:
(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDDDD BBBB CCCC
...
(gdb) x/32x 0x804c000
0x804c000: 0x00000000 0x00000029 0x41414141 0x41414141
0x804c010: 0x41414141 0x41414141 0x41414141 0x41414141
0x804c020: 0x41414141 0x41414141 0x44444444 0x00000044
0x804c030: 0x42424242 0x00000000 0x00000000 0x00000000
0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c050: 0x00000000 0x00000029 0x43434343 0x00000000
0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
...
(gdb) c
Program exited with code 021.
0x29を上書きしましたが、プログラムは正常に終了します。しかし、別のバイトを追加すると、セグメンテーション違反が発生します。
(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDDDD BBBB CCCC
...
(gdb) x/32x 0x804c000
0x804c000: 0x00000000 0x00000029 0x41414141 0x41414141
0x804c010: 0x41414141 0x41414141 0x41414141 0x41414141
0x804c020: 0x41414141 0x41414141 0x44444444 0x00004444
0x804c030: 0x42424242 0x00000000 0x00000000 0x00000000
0x804c040: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c050: 0x00000000 0x00000029 0x43434343 0x00000000
0x804c060: 0x00000000 0x00000000 0x00000000 0x00000000
0x804c070: 0x00000000 0x00000000 0x00000000 0x00000f89
...
(gdb) c
Program received signal SIGSEGV, Segmentation fault.
0x080498b9 in free (mem=0x804c030) at common/malloc.c:3631
私にとって最も重要な質問は次のとおりです。
free()
より多くのバイトを上書きすると、なぜセグメンテーション違反が発生するのですか?free()
アルゴリズムはどのように機能しますか?- そして、mallocとfreeはどのようにアドレスを追跡しますか?
読んでいただきありがとうございます、よろしくお願いします