尝试更改内存地址值时出现分段错误

时间:2015-08-10 18:16:18

标签: c segmentation-fault malloc

我发现了seg fault的错误,这个错误发生在我的divideBlock()函数中。当我取消引用newBlock来访问信息时,即没有为它赋值而只是解除引用它,它没关系,但是当我改变它的值时,我收到了一个设置错误。知道为什么会这样吗?可能是因为地址操作和非标准指针访问?如果是这样,如果我想将一个区块分成两个,我该怎么办?

typedef struct freeBlock
{
    size_t info;
    struct freeBlock *next;
} freeBlock;

freeBlock *divideBlock(freeBlock *block, size_t reqSize)
{
    // Declaration of variables.
    freeBlock *newBlock;
    size_t blockSize;

    blockSize = block->info >> 1;
    newBlock = block + reqSize;

    newBlock->info = (blockSize - reqSize) << 1; // new block marked as unused. seg fault happens here!!!
    block->info = (reqSize << 1) | 1; // old block marked as used.

    return newBlock;
}

void *malloc(size_t size)
{
    if (size == 0)
        return NULL;
    // Declaration of variables. 
    size_t blockSize, occpd, poccpd, reqSize;
    freeBlock *curr, *prev, *newBlock, *allocd, *combined;

    printf("%d", __LINE__);
    reqSize = (size + sizeof(size_t) + sizeof(char*) + padding + (align - 1)) & ~ (align - 1);

    printf("%d", __LINE__);
    curr = head;
    prev = NULL;
    while (curr != NULL)
    {
    printf("%d", __LINE__);
        occpd = curr->info & 1;

        if (prev != NULL)
        {
    printf("%d", __LINE__);
            poccpd = prev->info & 1;
            if (!poccpd && !occpd)
            {
                 combined = combineBlock(prev, curr);
                if (combined)
                    curr = combined;
            }
        }

        blockSize  = curr->info >> 1;

    printf("%d", __LINE__);
        if (blockSize >= reqSize && !occpd)
        {
            if (blockSize >= 2 * reqSize)
            {
                newBlock = divideBlock(curr, reqSize);
                if (newBlock != NULL)
                {
                    newBlock->next = curr->next;
                    curr->next = newBlock;
                }
            }
            curr->info |= 1;
            return curr + sizeof(char*) + sizeof(size_t);
        }
        prev = curr;
        curr = curr->next;
    }

    printf("%d", __LINE__);

    allocd = sbrk(reqSize * 3);
    if (allocd == (void*)-1)
        return NULL;

    allocd->info = ((reqSize * 3) << 1) | 1;
    newBlock = divideBlock(allocd, reqSize);
    newBlock->next = NULL;
    allocd->next = newBlock;

    if (head == NULL)
        head = allocd;
    else
        curr = allocd;

    return allocd + sizeof(char *) + sizeof(size_t);
}

1 个答案:

答案 0 :(得分:1)

问题似乎就在于:

newBlock = block + reqSize;

newBlock将指向一个位置(地址),即“block-of-block + reqSize * sizeof(freeBlock)”

可能只是意图是newBlock指向阻塞后的reqSize字节位置。

要将指针递增1,可以在添加reqSize之前将其强制转换为char *。

也许这样的分歧:

freeBlock *divideBlock(freeBlock *block, size_t reqSize)
{
    // Declaration of variables.
    freeBlock *newBlock;
    size_t blockSize;

    blockSize = block->info >> 1;
    newBlock = (freeBlock*)(((char*)block) + reqSize);

    newBlock->info = (blockSize - reqSize) << 1;
    block->info = (reqSize << 1) | 1; // old block marked as used.

    return newBlock;
}

但是在malloc函数中也存在问题,你在freeBlock类型的指针中添加数字。可能不是你想要的。

顺便说一句: 为什么使用

sizeof(char *) + sizeof(size_t)

不应该是

sizeof(freeBlock)