Удалить элемент из массива объектов - PullRequest
0 голосов
/ 02 октября 2019

Я пытаюсь разобраться с управлением памятью в C ++, поэтому я пишу карточную игру (в которой есть список карточек), но без использования vector.

. скажем, у меня есть массив Card s, как это: Card** cards. Теперь я хочу заменить карту с именем Card* remove на другую карту.

Я считаю, что все мои Card* в cards необходимо создать с помощью new,потому что другие функции должны обращаться к ним по указателю. Поэтому, когда я удаляю элемент из cards, мне также нужно delete.

Однако, когда я вызываю delete remove, он, кажется, портит мой массив. В частности, предположим, что remove произошло с индексом 2. Очевидно, до delete, cards[2] == remove. Однако после delete изменились и cards[2], и remove, тогда как указатель на cards одинаков.

Это может быть не плохо, но я очень запуталсяотносительно того, почему это происходит. В идеале я мог бы удалить память в куче, расположенной в remove, без изменения cards. Чего мне не хватает?

1 Ответ

1 голос
/ 02 октября 2019

Я сделал пример кода, который иллюстрирует то, что вы заявили. Но я не заметил, что вы сказали. Если бы вы могли показать свой код (минимальный и воспроизводимый пример), мы смогли бы найти то, что произошло.

Удаление указателя не изменяет значение указателя , но освобождает указанную значение .

Вот пример:

int main()
{
    typedef int Card;
    Card ** arr;

    // ---------- Init ----------
    arr = new Card* [5]; // five cards

    for(size_t i = 0; i < 5; ++i)
    {
        arr[i] = new Card(static_cast<int>(i));
    }
    // --------------------------

    // Direct removal
    std::cout << arr[2] << ": " << *arr[2] << '\n';
    delete arr[2];
    std::cout << arr[2] << '\n'; // >>>>> The address did not change after the deletion
    arr[2] = nullptr;

    std::cout << std::endl;

    // Delegated removal
    Card * to_remove = arr[3];
    std::cout << to_remove << " / " << arr[3] << " : " << *arr[3] << '\n';
    delete to_remove;
    std::cout << to_remove << " / " << arr[3] << '\n'; // >>>>> The address still did not change after deletion
    arr[3] = nullptr;

    // ----- Release memory -----
    for(size_t i = 0; i < 5; ++i)
        delete arr[i];

    delete[] arr;
    // --------------------------

    return 0;
}

Вывод:

0x2ea1c30: 2
0x2ea1c30

0x2ea5f40 / 0x2ea5f40 : 3
0x2ea5f40 / 0x2ea5f40

Как видите, значение указателя не изменилось.


Я думаю, важно отметить, что вы должны установить свои удаленные указатели на nullptr, поскольку они все еще находятся в вашем списке Card даже после удаления.

...