首页 文章

C中节点的内存分配

提问于
浏览
0

我正在为一个项目创建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指向块的 Headers . 我给它一个位置 . 问题是什么?

我的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;

2 回答

  • 1

    temp_node 设置在这里:

    temp_node = head_node + sizeof(block_header) + size;
    

    增量指针不按字节计算,地址根据指针指向的类型计算 . 因此,如果 p 指向 struct block_struct 数组的元素0,则 p+1 将指向索引1处的 struct block_structp+2 将指向索引2处的 struct block_struct .

    temp_node 的初始化似乎假设 head_node 将增加若干字节 .

    您可以更改计算以在 struct block_struct 上工作,也可以在执行指针算法之前将指针转换为 char*char 是一个字节) .

  • 2

    您会因指针算法与类型的交互方式而惹恼 .

    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&R中所述 .

    union align_storage {
        most_strictly_aligned_type x; /* Usually a long; sometimes long long */
        char storage[BLOCK_SIZE];
    };
    

相关问题