c - 双参考循环变量在循环更新时发生变化
问题描述
经过多次挠头后,我想我已经发现了这个问题。编码:
struct Block {
union {
void* address;
Block* next;
};
size_t size;
};
void* FragmentedMemoryManager::allocate(size_t size) {
if(allocationCount == maxAllocations) return nullptr;
Block** prev = &head;
Block* curr = head;
for(;
curr != nullptr;
prev = &curr,
curr = curr->next
)
{
if(curr->size < size) {
continue;
}
Block allocBlock = Block{
address: curr,
size: size
};
allocations[allocationCount++] = allocBlock;
size_t newSize = curr->size - size;
//pretty sure this will wrap if it goes 'negative'
assert(newSize < curr->size);
//curr was completely allocated
if(newSize == 0) {
*prev = curr->next;
} else {
void* newAddress = toPtr(toUPtr(curr) + size);
Block* newBlock = reinterpret_cast<Block*>(newAddress);
newBlock->next = curr->next;
newBlock->size = newSize;
if(*prev == head) {
*prev = newBlock;
} else {
//I know that this fails because prev is a double ref,
//updating curr in the loop unintentionally updates prev
//see line 36
(*prev)->next = newBlock;
}
}
std::sort(
allocations, allocations + allocationCount,
[](Block a, Block b)
{
return a.address < b.address;
});
memset(allocBlock.address, 0, size);
return allocBlock.address;
}
return nullptr;
}
我确信这个想法是正确的,因为我需要做 (*prev)->next = newBlock,我不知道如何在更新 curr 的同时保留 prev 的预期引用。我该怎么做呢?
缩进很奇怪。因为这里发生的事情不仅仅是添加到列表中。prev 有可能完全跳过 curr,本质上是“删除”curr。我将节点直接写入未分配的内存区域。
解决方案
我想你只是想要这个:
Block* curr = head;
Block* prev = NULL;
while (curr)
{
prev = curr;
curr = curr->next;
}
if (prev)
{
prev->next = newBlock;
}
else
{
head = newBlock;
}
newBlock->next = NULL;
推荐阅读
- python-3.x - Spacy 相似性警告:“基于空向量评估 Doc.similarity。”
- hive - HiveAccessControlException 权限被拒绝:用户没有 [ALL] 权限
- gnuplot - Gnuplot 整数溢出
- java - 忽略 JSON 到 XML 转换中的键
- java - 在具有命名空间的 Java 中针对模式的 XML 验证失败
- tfs - 我应该将自定义构建步骤放在 MSBuild 还是 TFS/Azure DevOps 构建管道中?
- android - 为什么来自 PWA 的 web apk 没有 Internet 权限?
- python - 如何确定客户端是否在 tkinter 消息框中选择了“ok”?
- python-3.x - 如何在 Python 中使用“尝试写入小于 Content-Length 的 x 字节”来修复龙卷风错误
- arrays - Countifs 公式在使用数组排除时不起作用,但适用于包含