Двойная ссылка l oop изменение переменной при обновлении l oop - PullRequest
0 голосов
/ 24 января 2020

После долгих царапин на голове, думаю, я заметил проблему. Код:

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, я не знаю, как сохранить предполагаемую ссылку на prev, пока также обновление curr. Как мне это сделать?

Отступ вышел шатким. Поскольку здесь происходит нечто большее, чем просто добавление в список. Существует возможность предварительного перепрыгивания через курсор, по сути, «удаления» курсора. Я пишу узлы прямо в нераспределенные области памяти.

1 Ответ

1 голос
/ 24 января 2020

Я думаю, вы просто хотите это:

Block* curr = head;
Block* prev = NULL;
while (curr)
{
    prev = curr;
    curr = curr->next;
}
if (prev)
{
    prev->next = newBlock;
}
else
{
   head = newBlock;
}
newBlock->next = NULL;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...