我发现了一个段错误错误,该错误恰好出现在我的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/