c - 尝试更改内存地址处的值时出现段错误

标签 c segmentation-fault malloc

我发现了一个段错误错误,该错误恰好出现在我的divideBlock() 函数中。当我取消引用 newBlock 来访问信息时,即不为其赋值而只是取消引用它,这是好的,但是当我更改其值时,我收到了一个设置错误。知道为什么会发生这种情况吗?难道是因为地址操作和非标准指针访问?如果是的话,如果我想把一个方 block 分成两半该怎么办?

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);
}

最佳答案

问题似乎出在这一行:

newBlock = block + reqSize;

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

可能的目的很简单,newBlock 应指向 block 之后的位置 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)

关于c - 尝试更改内存地址处的值时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31926405/

相关文章:

c++ - 阵列访问期间的段错误

c++ - 函数指针返回值时出现奇怪的段错误

c - C 中的动态分配和释放

c - malloc 和 calloc

C++:gcc 4.2.1 给出了段错误的程序,而不是在 linux 上

c - 最大分配大小

c - 在 C 中 fork 后从 SHM 编辑结构中的变量

计算C中结构体数组中的唯一元素

c - 如何查找数组中整数之间是否存在共同差异?

c - 在 C 中打印不需要的空行