尝试从堆保留中手动分配内存。使用以下命令分配1MB的堆空间:
partition = *(partition_t*) malloc(1048576*sizeof(partition_t));
其中'partition'是单个char(1字节)的结构:
typedef struct {
char dummy;
}partition_t;
稍后在代码中,包含有关分区的元数据的struct meta_t被放置在每个分区的前40个字节中,使用:
boolean start_memory(partition_t *partition_ptr, global_memory_info_t *global_memory_info_ptr)
{
boolean initialized = False;
partition_meta_t meta;
if (partition_ptr != NULL)
{
global_memory_info_ptr->memory_size = SIZE;
global_memory_info_ptr->free_memory = SIZE;
global_memory_info_ptr->used_memory = 0;
global_memory_info_ptr->block_base_address = partition_ptr;
meta.size = SIZE;
meta.available = True;
meta.start_address = partition_ptr;
meta.used_memory = 0;
meta.extra_memory = 0;
meta.next_partition = NULL;
meta.prev_partition = NULL;
*((partition_meta_t *)partition_ptr) = meta;
initialized = True;
}
return initialized;
}
元数据还可以作为链接列表来跟踪其他分区。
内存大小请求的二进制倍数(2 ^ n)由用户进行,并且分区重复减半,直到找到适当的块。检查适当的大小是在其他地方完成的。下面的函数将传递的分区减半,并将元数据附加到新分区的起始地址。
void mem_chopper(partition_t *partition_ptr)
{
partition_meta_t meta;
int start_address_offset = ((partition_meta_t *)(partition_ptr))->size / 2 ;
meta.start_address = ((partition_meta_t *)(partition_ptr))->start_address + (((partition_meta_t *)(partition_ptr))->size / 2);
meta.available = True;
meta.size = start_address_offset;
meta.used_memory = 0;
meta.extra_memory = 0;
meta.next_partition = NULL;
meta.prev_partition = NULL;
((partition_meta_t *)(partition_ptr))->next_partition = meta.start_address;
((partition_meta_t *)(partition_ptr))->size = start_address_offset;
meta.prev_partition = ((partition_meta_t *)(partition_ptr))-> start_address;
*((partition_meta_t *)meta.start_address) = meta;
}
问题是:mem_chopper()函数将在第一次执行时正常执行并划分初始分区并将元数据放在新分区中。但是,在再次划分分区的第二遍中,我将得到一个EXC_BAD_ACCESS(代码= 2,地址= 0x100041038)。
地址重合,0x100041038,恰好是原始1MB内存的1/4。当我分配2MB的堆空间时,程序仍然在地址0x100041038处崩溃,现在是已分配内存的1/8。
为什么这会与EXC_BAD_ACCESS崩溃(代码= 2,地址= 0x100041038)?
整个代码如下: https://www.dropbox.com/s/1ykxan6n9h700wi/Ass5v3.zip?dl=0
堆大小在mem_commands.h中由变量SIZE定义。