したがって、私の学校の課題の1つでは、独自のメモリ割り当てパッケージを実装する必要があります。メモリの空きブロックを表す構造体ブロックを使用して、メモリヒープの空きスペースがどこにあるかを示すブロックのリストを作成します。これは「空きリスト」とも呼ばれます。以下は私が作成したブロック構造体です。
typedef struct block {
struct block *next;
struct block *prev;
int size;
unsigned char *buffer;
} block;
my_malloc()の実装(以下を参照)は、私のテストでは正常に機能しているようです。
void *my_malloc(int size){
//if my_malloc has never been called before create the first
// free block who's data buffer spans the entire heap
if(!initialized){
initialized = 1; //Next time, we've already inited
// Create the first block
*(block *)head = (block){NULL, NULL, 0, NULL};
block *p = (block *)head;
//try setting size to 128KB and point buffer properly
p->size = 1024*128;
p->buffer = p+ 1;
printf("Address of buffer is %p\n", p->buffer);
// set the program break
brk(head + (sizeof(block)+p->size));
}
block *p = (block *)head; //point to the head, we don't want to move the head...
// find the appropriate free block and check for nullity
block *selected = find_block(size);
if(selected==NULL){
printf("Had no space first time around!\n");
//go to the end of the free list
while(p->next!=NULL){
p=p->next;
}
// increase it's size by 128KB
p->size=p->size+(128*1024);
// move the program break by additional 128KB
sbrk(128*1024);
//now the last free block has enough space, so make it the selected block
selected=p;
}
block *new_block; // new block we will create
// if the block we have to allocate is pointed by head, we need a new
// head
if ((block *)selected==(block *)head){
//shift head
head = selected->buffer+ size;
//Create a new block there, it wil be our new head and we don't return it
*(block *)head = (block){NULL, NULL, 0, NULL};
block *new_block = (block *)head;
new_block->prev = selected->prev;
new_block->next = selected->next;
new_block->size = selected->size-size;
new_block->buffer = new_block +1;
printf("The split new_block->buffer points to %p\n", new_block->buffer);
//return the pointer to original head, not the new one.
total_malloced=+size;
return selected->buffer;
}
// The selected node is not the head so we don't move the head
else{
new_block = selected->buffer+size;
new_block->prev = selected->prev;
new_block->next = selected->next;
new_block->size = selected->size-size;
new_block->buffer = new_block +1;
//remove that selected block from the free list
(selected->prev)->next=new_block;
total_malloced=+size;
return selected->buffer;
}
}
この問題は、返されたmy_mallocのポインターをmy_free()などのメソッドに送信するときに発生します。
void my_free(void *ptr) {
printf("Dummy instruct.\n");
}
次のエラーが発生します。
*** glibc detected *** ./myMalloc: munmap_chunk(): invalid pointer: 0x0804a17e ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xb7e7cee2]
/lib/i386-linux-gnu/libc.so.6(+0x765c5)[0xb7e7d5c5]
./myMalloc[0x80485b1]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb7e204d3]
./myMalloc[0x8048401]
======= Memory map: ========
08048000-08049000 r-xp 00000000 00:3d 8557227 /home/2009/gkrink/os/myMalloc
08049000-0804a000 r--p 00000000 00:3d 8557227 /home/2009/gkrink/os/myMalloc
0804a000-0804b000 rw-p 00001000 00:3d 8557227 /home/2009/gkrink/os/myMalloc
0804b000-0808c000 rw-p 00000000 00:00 0 [heap]
b7e06000-b7e07000 rw-p 00000000 00:00 0
b7e07000-b7faa000 r-xp 00000000 00:11 4370765 /lib/i386-linux-gnu/libc-2.15.so
b7faa000-b7fab000 ---p 001a3000 00:11 4370765 /lib/i386-linux-gnu/libc-2.15.so
b7fab000-b7fad000 r--p 001a3000 00:11 4370765 /lib/i386-linux-gnu/libc-2.15.so
b7fad000-b7fae000 rw-p 001a5000 00:11 4370765 /lib/i386-linux-gnu/libc-2.15.so
b7fae000-b7fb1000 rw-p 00000000 00:00 0
b7fbb000-b7fd7000 r-xp 00000000 00:11 6829467 /lib/i386-linux-gnu/libgcc_s.so.1
b7fd7000-b7fd8000 r--p 0001b000 00:11 6829467 /lib/i386-linux-gnu/libgcc_s.so.1
b7fd8000-b7fd9000 rw-p 0001c000 00:11 6829467 /lib/i386-linux-gnu/libgcc_s.so.1
b7fd9000-b7fdd000 rw-p 00000000 00:00 0
b7fdd000-b7fde000 r-xp 00000000 00:00 0 [vdso]
b7fde000-b7ffe000 r-xp 00000000 00:11 4370778 /lib/i386-linux-gnu/ld-2.15.so
b7ffe000-b7fff000 r--p 0001f000 00:11 4370778 /lib/i386-linux-gnu/ld-2.15.so
b7fff000-b8000000 rw-p 00020000 00:11 4370778 /lib/i386-linux-gnu/ld-2.15.so
bffdf000-c0000000 rw-p 00000000 00:00 0 [stack]
Aborted
そして、これが私のテスト機能です:
void main(void){
printf("Testing initiated...\n");
printf("head is located at %p\n\n", head);
void * tester;
printf("mallocing 100...\n");
tester = my_malloc(100);
printf("The allocated memory starts at %p\n", tester);
printf("mallocing 150...\n");
tester=my_malloc(150);
printf("The allocated memory starts at %p\n", tester);
printf("head is located at %p\n\n", head);
printf("brk is firstly located at %p\n", sbrk(0));
printf("mallocing 10...");
tester=my_malloc(10);
printf("The allocated memory starts at %p\n", tester);
printf("brk is still at %p\n", sbrk(0));
free(tester);
}
そして、返されたmy_malloc()のポインターをmy_free()に送信せずに、次のような正しい出力を取得します。
テストが開始されました...ヘッドは0x804a054にあります
mallocing100...バッファのアドレスは0x804a064です。splitnew_block->bufferは0x804a0d8を指します。割り当てられたメモリは0x804a064で始まります。mallocing150...splitnew_block->bufferは0x804a17eを指します。
brkは最初に0x806a064mallocing10にあります...分割されたnew_block->bufferは0x804a198を指します割り当てられたメモリは0x804a17eから始まりますbrkはまだ0x806a064にあります
そのような別の関数へのポインタを送信できないのはなぜですか?