Безопасно ли использовать realloc после оператора new в C++?

Насколько я знаю, нет точной альтернативы realloc из C в C++, как new для malloc. Однако, когда я использую realloc в C++ для изменения памяти, выделенной оператором new, все работает нормально.

Безопасно ли использовать эти два (new и realloc), как я делаю в приведенных ниже кодах, или это может привести к некоторым проблемам?

#include <iostream>
#include <cstdlib>

int main()
{
    int size = 5;
    int * arr = new int[size]{ 1,3,5,7,9 };

    for (int i = 0; i < size; i++)
        std::cout << *(arr + i) << (i < size - 1 ? ' ' : '\n');

    size++;
    arr = (int*)realloc(arr, size * sizeof(int));

    *(arr + size - 1) = 11;
    for (int i = 0; i < size; i++)
        std::cout << *(arr + i) << (i < size - 1 ? ' ' : '\n');

    delete[] arr;
    //free(arr);

    std::cin.get();
    return 0;
}

Кроме того, какой оператор я должен использовать в таком случае для освобождения памяти: delete[] из free()?


person L_J    schedule 09.07.2018    source источник
comment
Нет, вместо этого используйте std::vector   -  person NathanOliver    schedule 09.07.2018
comment
Библиотека времени выполнения просто не старается сделать это намеренно неудачным. Однако это пламенный UB, когда тип элемента является объектом C++, например std::string. Внутренние указатели не будут обновляться.   -  person Hans Passant    schedule 09.07.2018
comment
@HansPassant С какой стати кому-то делать это с std::string? Или действительно любой библиотечный объект? Все, что можно потерять, ничего не приобрести (если, возможно, вы совершенно неправильно понимаете std::vector или std::array).   -  person Paul Sanders    schedule 09.07.2018
comment
И, что интересно, поскольку new и malloc выделены из разных куч, Edit n Continue не работало в VS2015, я думаю, что это было, потому что, как я обнаружил после изрядного копания, что-то было выделено с malloc и позже освобождено с delete . Я пропатчил mspdsrv и поплыл в свое удовольствие (потом исправили). По иронии судьбы, ошибка была «проглочена» какой-то недопустимой логикой обработки параметров, поэтому разработчик, который сделал эту ерунду, никогда не видел никаких доказательств этого (кроме того факта, что его код на самом деле не работал).   -  person Paul Sanders    schedule 09.07.2018


Ответы (3)


Нет, поведение не определено. Вы можете вызвать delete[] только по указателю, который вы получили от вызова new[].

Использование std::vector приведет к исчезновению всех этих проблем с памятью.

person Bathsheba    schedule 09.07.2018
comment
документация realloc говорит: перераспределяет заданную область памяти. Он должен быть предварительно выделен функциями malloc(), calloc() или realloc() и еще не освобожден вызовом функций free или realloc. В противном случае результаты не определены. - person Paul Belanger; 09.07.2018

Это небезопасно. new должен совпадать только с delete или delete[] — использование его с realloc опасно и может привести к угрозе безопасности.

Кроме того, почему вы используете new и delete в первую очередь? Используйте контейнеры, такие как std::vector, или интеллектуальные указатели, такие как std::unique_ptr, если вы действительно хотите управлять памятью самостоятельно.

person Vittorio Romeo    schedule 09.07.2018

Не смешивайте функции памяти C с функциями памяти C++, иначе у вас будут плохие времена.

См. это: Что такое C++ версия realloc() для выделения нового буфера и копирования содержимого из старого?

person Hongyu Wang    schedule 09.07.2018
comment
Как этот ответ должен быть комментарием - person NathanOliver; 09.07.2018