堆是以下定义的结构的链接列表:

struct block
{
/*header + block*/
bool freeSpace;
block * prev;
block * next;
size_t size;
char block_part[];
};

我正在处理以下案件:
如果我找到的第一块内存太大,它可以容纳新分配的
另外一个街区,然后这个街区被分成两块;一个街区用来容纳新的
分配的块和剩余的空闲块。
(注意,如果它比我需要的大一点,但不是很大
足够一个新的块(即它不够大,不能容纳一个新块的元数据),我将在块的末尾有未使用的空间
我的代码如下。当我专门测试这个案例时,我的程序会因为segfault而崩溃。有人能看看有什么问题吗?谢谢。
do{
    if (ptr -> freeSpace && ptr -> size >= size){
        /*first suffient free block is found*/
        ptr -> freeSpace = false;

        if (ptr -> size > size + sizeof(struct  block)){
            /*if big enought for 'size' AND metadata of a new block, split the block*/
            struct block * returnPtr = memset((ptr -> block_part), 0, size);
            struct block * added = returnPtr + size;
            added -> size = ptr -> size - size - sizeof(struct block);
            added -> freeSpace = true;
            added -> prev = ptr;
            added -> next = ptr -> next;
            (ptr -> next) -> prev = added;
            ptr -> next = added;
            ptr -> size = size;
            return returnPtr;

            }
        ptr -> size = size;
        return memset((ptr -> block_part), 0, size);

        }
    prevPtr = ptr;
    ptr = ptr -> next;


}while (ptr);

最佳答案

Memset返回一个void *。它不会发出警告,因为void指针是由编译器自动生成的(例如malloc(non-)cast)。

struct block *returnPtr = memset((ptr->block_part), 0, size);

为什么要为具有多个成员的整个结构浪费内存来存储指向字符的空指针?
之后,使用now void指针的地址并将其向前移动size-number。然后将其视为已分配的结构。这会导致added根本没有被分配(如果size大于strlen(ptr->block_part)+1你已经在别人的记忆中),或者至少破坏了记忆。访问这样的内存会产生一个错误的程序。
因此,您观察到分段错误,程序崩溃。
注意:到目前为止,我还没有看到有人用这种方式使用memset返回值。

关于c - 实现Malloc:分割块的情况,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36251458/

10-14 14:48