Использование деструктора для удаления только динамически распределяемых массивов или всех массивов? - PullRequest
0 голосов
/ 05 декабря 2018

Я новичок в C ++, поэтому я много борюсь с управлением памятью.Я знаю, что когда у нас есть указатель на массив, это означает, что он создается динамически, поэтому я должен удалить его позже в моем деструкторе.Но что, если у нас есть нормальный массив, нужно ли включать оператор удаления в деструктор и для этого нормального массива?или программа сделает это автоматически?например, у меня есть обычный массив, подобный этому int myArray[];, и в моем деструкторе я должен включить это: delete[] myArray;?Заранее спасибо,

Ответы [ 4 ]

0 голосов
/ 06 декабря 2018

Что я получил из ответов, так это то, что мне не нужно ничего delete, если new не запущено.То же самое относится к delete[] и new[].Обычно создаваемые массивы, такие как в моем вопросе int myArray[], не создаются динамически, поэтому их не нужно динамически удалять в деструкторе. Это означает, что компилятор выполнит за меня удаление.Спасибо всем

0 голосов
/ 05 декабря 2018

Я знаю, что когда у нас есть указатель на массив, это означает, что он динамически создается

Нет.Эта индукция не верна.Указатель также может указывать на нединамически созданные массивы.

, поэтому я должен удалить его позже в моем деструкторе.

Если экземпляр вашего класса отвечает за его уничтожениеМассив, тогда деструктор действительно является тем местом, где это, вероятно, должно быть сделано.

нужно ли включать оператор удаления в деструктор и для этого обычного массива?например, у меня есть обычный массив, как этот int myArray [];

Нет.Только объекты, созданные с помощью new, уничтожаются с помощью delete.И только объекты, созданные с new[], уничтожаются с delete[].Ничего другого.

или программа сделает это автоматически?

Да.

Объекты с автоматическим хранением уничтожаются автоматически в концеобласть, где они объявлены.Отсюда и название класса хранения.Объекты со статической продолжительностью хранения уничтожаются после возврата main.Временные объекты уничтожаются в конце полного выражения (если только их время жизни не увеличивается путем привязки объекта к ссылке).Переменные-члены уничтожаются, когда уничтожается супер (не означающий базовый класс в данном контексте).

Только динамически созданные объекты должны быть уничтожены вручную.


Хотя это полезно для изучениякак это делается, очень редко требуется ручное управление памятью в C ++.Стандартная библиотека предоставляет контейнеры, которые выполняют тяжелую работу за вас.Вместо динамического создания массива обычно используют std::vector.

0 голосов
/ 06 декабря 2018

Управление памятью непросто для всех, особенно для новичков в C ++.Я рекомендую изучить термины stack и heap, которые, как мы надеемся, должны прояснить некоторые вопросы.

Я знаю, что когда у нас есть указатель на массив, это означает, что он создается динамически,поэтому я должен удалить его позже в моем деструкторе.

Это не совсем так, указатель - это просто переменная, которая содержит адрес (где живет переменная) чего-либо.Вы можете сделать указатель на любую переменную, подобную этой:

int a = 5;
int *aPtr = &a;

Это не означает, что a или aPtr являются динамическими.

Однако указатель, созданный таким образом, будетдинамический и должен быть удален:

int *aPtr = new int(5);

Самым большим отличием здесь является ключевое слово new.new создает динамическую память (что помещается в кучу).Каждый раз, когда вы используете ключевое слово new, вы должны использовать ключевое слово delete, чтобы соответствовать ему.

Но что, если у нас есть обычный массив, мне нужно включить оператор удаления вдеструктор для этого обычного массива тоже?или программа сделает это автоматически?например, у меня есть обычный массив, подобный этому int myArray[];, и в моем деструкторе я должен включить это: delete[] myArray;?

Нет, вам не нужно было бы вызывать delete[] myArray;, потому что этомассив будет сделан в стеке.Под этим я подразумеваю, что при возврате из функции, создавшей этот массив, массив будет очищен из памяти.

Альтернативой ручному управлению памятью является использование std::array, * 1035.* или даже умные указатели, такие как std::unique_ptr или std::shared_ptr, которые очищаются после того, как ссылка на них исчезла.

Надеюсь, это поможет!

0 голосов
/ 05 декабря 2018

Но что, если у нас есть нормальный массив, нужно ли включать оператор удаления в деструктор и для этого нормального массива?или программа сделает это автоматически?например, у меня есть обычный массив, подобный этому int myArray[];, и в моем деструкторе я должен включить это: delete[] myArray;?

Нет.Если вы не new[] массив, то вам не нужно delete[] его.Все остальное делается автоматически.Вот почему использование std::array, std::vector и т. Д. Так здорово: вам не нужно писать new[], когда вы их используете, так что вам не нужно беспокоиться, что вы, возможно, забыли delete[].

«Я знаю, что когда у нас есть указатель на массив, это означает, что он создается динамически» *

Это не правильно.Вы можете взять указатель на что угодно, включая переменные стека.Динамическое распределение обычно возвращает вам указатель (который, вероятно, является источником путаницы), но не каждый указатель происходит от динамического выделения.Учтите это:

void foo()
{
    int a;
    int* b = &a; // No dynamic allocation.
}

Опять же, поскольку здесь нет new, не должно быть delete.

...