我正在为一个项目创建malloc,并以很难的方式分配空间来理解它是如何工作的,但是我得到了空指针问题。
(给定)块结构:链接列表
typedef struct block_hd{
/* The blocks are maintained as a linked list */
/* The blocks are ordered in the increasing order of addresses */
struct block_hd* next;
int size_status;
}block_header;
block_header* list_head = NULL;
当我添加内存块时,我遇到了临时节点的错误。基本上,它不会取消引用temp_node到达下一个并将其设置到正确的位置。 我的打印声明:
not empty: 4088
there is space to add
create temp
f7758040
f7754000
00000000
Segmentation fault (core dumped)
它永远不会到达temp_node的下一个。就像它没有正确创造温度。 Temp指向块的标题。我给它一个位置。有什么问题?
我的Mem_Alloc函数*假设正确启动的链表:
void* Mem_Alloc(int size)
{
if (size < 1) return NULL;
size = 1 + ((size - 1)/4);
size = size * 4;
if (list_head != NULL){
block_header* head_node = list_head;
while (head_node != NULL){
//get curr header size
int node_size = head_node->size_status;
printf("not empty: %d\n", node_size);
//there is space to add
if (node_size%2 == 0 && (size+sizeof(block_header)) < node_size){
printf("there is space to add\n");
//twocases
if ((node_size - size - sizeof(block_header)) > 0){
printf("create temp\n");
block_header* temp_node = NULL;
temp_node = head_node + sizeof(block_header) + size;
printf("%08x\n", (unsigned int) temp_node);
printf("%08x\n", (unsigned int) head_node);
printf("%08x\n", (unsigned int) head_node->next);
printf("%08x\n", (unsigned int) temp_node->next);
printf("set temp next to head next\n");
temp_node->next = head_node->next;
printf("set temp size to remaining\n");
temp_node->size_status = (head_node->size_status - sizeof(block_header) - size);
printf("set head size to used status\n");
head_node->size_status = size + 1;
printf("set head next to temp\n");
head_node->next = temp_node;
}
else{
//if at end, and not enough space for another header
//keep current size_status - do not reduce current
printf("Not enough space, set head size to used\n");
if (head_node->next != NULL) head_node->size_status = size + 1;
}
//return location of (head_node_location+sizeof(block_header))
return head_node + sizeof(block_header);
}//end if
else{
//headersize%2 equaled 1, so it's used - move on.
printf("STEPPING THROUGH LINKED LIST\n");
head_node = head_node->next;
}
}//end while
}//end if
return NULL;
答案 0 :(得分:2)
temp_node
设置在此处:
temp_node = head_node + sizeof(block_header) + size;
递增指针不按字节计算,地址根据指针指向的类型计算。因此,如果p
指向struct block_struct
数组的元素0,那么p+1
将指向索引1处的struct block_struct
,p+2
将指向一个temp_node
在索引2。
head_node
的初始化似乎假设struct block_struct
将增加若干字节。
您可以更改计算以使用char*
,也可以在执行指针算术之前将指针转换为char
(<{1}}是一个字节)。
答案 1 :(得分:1)
指针算术与类型的交互方式让你感到懊恼。
temp_node = head_node + sizeof(block_header) + size;
我假设在这一行中你试图推进指针size + sizeof(block_header)
字节。但由于指针是block_headers,因此它按字节数乘以sizeof(block_header)。你可以这样做:
/* Advance the pointer then cast */
char *raw_tmp_node = head_node + sizeof(block_header) + size;
block_header *tmp_node = (block_header*)raw_tmp_node;
顺便说一下,您应该了解内存对齐的重要性。 malloc
保证它返回的内存适合任何类型。通常,这通过强制与联合对齐来完成,如K&amp; R中所述。
union align_storage {
most_strictly_aligned_type x; /* Usually a long; sometimes long long */
char storage[BLOCK_SIZE];
};