Почему там новое специальное предложение, и удалите для массивов?

Во-первых, убедитесь, что ваша система полностью обновлена:

sudo apt update
sudo apt upgrade

Далее, установите набор инструментов GCC по умолчанию с помощью:

sudo apt install build-essential

Далее нам нужно установить несколько предварительных условий сборка Python:

sudo apt install libssl-dev zlib1g-dev libncurses5-dev libncursesw5-dev libreadline-dev libsqlite3-dev

sudo apt install libgdbm-dev libdb5.3-dev libbz2-dev libexpat1-dev liblzma-dev libffi-dev

На момент написания этой статьи последняя стабильная версия Python - 3.7.1. Если вы хотите использовать более новую версию, измените следующие инструкции соответственно:

wget https://www.python.org/ftp/python/3.7.1/Python-3.7.1.tar.xz
tar xf Python-3.7.1.tar.xz
cd Python-3.7.1
./configure --enable-optimizations
make -j 8
sudo make altinstall
11
задан Sam 10 August 2014 в 10:28
поделиться

7 ответов

Объекты, созданные с new[] должен использовать delete[]. Используя delete не определено на массивах.

С malloc и свободный у Вас есть более простая ситуация. Существует только 1 функция, которая освобождает данные, которые Вы выделяете, нет никакого понятия деструктора, называемого также. Беспорядок просто входит потому что delete[] и удалите подобный взгляд. На самом деле они - 2 совершенно других функции.

Используя удаляют, не вызовет корректную функцию для удаления памяти. Это должно звонить delete[](void*) но вместо этого это звонит delete(void*). Поэтому Вы не можете полагаться на использование delete для памяти, выделенной с new[]

Посмотрите этот FAQ C++

[16.13] Я могу отбросить [] когда deleteing массив некоторого встроенного типа (символ, интервал, и т.д.)?

Нет!

Иногда программисты думают что [] в delete[] p только существует так, компилятор назовет соответствующие деструкторы для всех элементов в массиве. Из-за этого обоснования они предполагают что массив некоторого встроенного типа такой как char или int может быть deleted без []. Например, они предполагают, что следующее является действительным кодом:

void userCode(int n)  {
    char* p = new char[n];
    ...
    delete p; // ← ERROR! Should be delete[] p !
}

Но вышеупомянутый код является неверным, и он может вызвать аварию во времени выполнения. В частности, код это требуется delete p operator delete(void*), но код это требуется delete[] p operator delete[](void*). Поведение по умолчанию для последнего состоит в том, чтобы назвать первого, но пользователям разрешают заменить последнего другим поведением (в этом случае, они обычно также заменяли бы соответствующий новый код в операторе new[](size_t)). Если они заменили delete[] кодируйте, таким образом, это не было совместимо с удалить кодом, и Вы назвали неправильный (т.е. если Вы сказали delete p вместо delete[] p), Вы могли закончить с аварией во времени выполнения.

Почему делает delete[] существовать во-первых?

Делаете ли Вы x или y:

 char * x = new char[100]; 
 char * y = new char;

Оба хранятся в char * переменные определенного типа.

Я думаю причина решения о delete, и delete[] соглашается с длинным списком решений, которые выступают за эффективность в C++. Это - так, чтобы не было никакой вынужденной цены, чтобы сделать поиск того, насколько потребности, которые будут удалены для нормального, удаляют операцию.

Наличие 2 new и new[] кажется только логичным, чтобы иметь delete и delete[] так или иначе для симметрии.

14
ответ дан 3 December 2019 в 01:53
поделиться

Различие - это delete только удалит весь диапазон памяти, но только назовет деструктор для 1 объекта. delete[] и удалит память и назовет деструктор для каждого объекта. Если Вы не используете delete[] для массивов это - только вопрос времени, прежде чем Вы введете утечку ресурсов в свое приложение.

Обновление РЕДАКТИРОВАНИЯ

Согласно стандарту, передавая объект, выделенный с new[] кому: delete не определено. Вероятное поведение состоит в том, что это будет действовать, как я описал.

12
ответ дан 3 December 2019 в 01:53
поделиться

Stroustrup говорит о причинах отдельного new/new[] и delete/удалите []' операторы в "Дизайне и Эволюции C++" в разделах 10.3 до 10.5.1:

  • 10.3 Распределение массива - обсуждает это, они хотели способ позволить массивам объектов быть выделенными с помощью отдельной схемы от отдельных объектов выделения (т.е., выделяя массивы от отдельного хранилища). Добавление версий массива new и delete было решение для этого;
  • 10.5.1 Освобождение Массивов - обсуждает как проблема с освобождением массивов, использующих просто сингл delete оператор - то, что должно быть больше информации, чем просто указатель, чтобы определить, указывает ли указатель на первый элемент массива или если это просто указывает на отдельный объект. Вместо того, чтобы "усложнить общий падеж выделения и освобождения отдельных объектов", delete[] оператор используется для обработки массивов. Это согласуется с общей философией дизайна C++, "не платят за то, что Вы не используете".

Было ли это решение ошибкой или не спорно - так или иначе имеет хорошие аргументы, но мы имеем то, что мы имеем.

5
ответ дан 3 December 2019 в 01:53
поделиться

Относительно, "почему" в заголовке: одна из целей дизайна C++ была то, что не будет никаких скрытых затрат. C++ был также разработан в то время, когда каждый байт памяти все еще имел значение намного больше, чем это делает сегодня. Разработчики языка также как ортогональность: если Вы выделяете память с new[] (вместо new), необходимо освободить его с delete[].

Я не думаю, что существует любая техническая причина это new[] не мог засунуть флаг "I am an array" в заголовок блока памяти для delete (не больше delete[]) посмотреть на позже.

1
ответ дан 3 December 2019 в 01:53
поделиться

new и delete отличаются от malloc и free в этом malloc и free только выделите и свободная память; они не называют ctors или dtors.

1
ответ дан 3 December 2019 в 01:53
поделиться

Причина этого требования является исторической и потому что new type и new type [size] возвратите разные вещи, которые должны быть очищены по-другому.

Рассмотрите этот код

Foo* oneEntry = new Foo;
Foo* tenEntries = new Foo[10];

Они оба возвращают Нечто* указатель, различием является второй вызов, приведет к конструктору Foo, вызываемому 10x, и там являющийся примерно 10x столько же памяти.

Таким образом, теперь Вы хотите освободить свои объекты.

Для отдельного объекта Вы звонили бы, удаляют - например. delete oneEntry. Это называет деструктор объектов и и освобождает память.

Но вот проблема - oneEntry, и аренда является оба просто указателями Foo. Компилятор понятия не имеет, указывают ли они на один, десять, или тысяча элементов.

Когда Вы используете специальный синтаксис delete []. Это говорит компилятору, что "это - массив объектов, выясните количество и затем разрушьте их всех".

То, что действительно происходит, является этим для new type [size] компилятор тайно хранит 'размер' где-то в другом месте. Когда Вы звоните, удаляют [], это знает, что это секретное значение существует так, это может узнать, сколько объектов находится в том блоке памяти и разрушает их.

Вопрос, который Вы могли затем задать, "почему компилятор не всегда хранит размер?"

Это - большой вопрос, и он относится ко времени первых лет C++. Было требование, что для встроенных типов (символ, интервал, плавание, и т.д.) следующее будет допустимо для C++;

int* ptr = new int;
free(ptr);

int* ptr = (int*)malloc(sizeof(int) * someSize);
delete ptr;

Обоснование позади этого было ожиданием, что люди обеспечат библиотеки, которые возвратили динамично выделенную память, и у пользователей этих библиотек не будет способа знать, использовать ли, освобождают/удаляют.

Это требование совместимости означало, что размер массива не мог быть сохранен как часть самого массива и должен был быть сохранен в другом месте. Из-за этих издержек (и помнят, это вернулось в начале 80-х), было решено сделать эту бухгалтерию только для массивов и не единственных элементов. Таким образом потребность массивов, специальное предложение удаляет синтаксис, который ищет это значение.

Причина malloc/free не имеет этой проблемы, то, что они просто имеют дело с блоками памяти и не должны волноваться о звонящих конструкторах/деструкторах.

3
ответ дан 3 December 2019 в 01:53
поделиться

Когда Вы используете new[] для выделения массива Вы на самом деле говорите C++ размер массива. Когда Вы используете malloc, Вы вместо этого говорите это, сколько памяти выделяется. В бывшем случае, освобождающем на основе размера массива, не имел бы смысла. В этом случае это делает. Но с тех пор нет никакого различия между указателем для массива по сравнению с для отдельного объекта, отдельная функция необходима.

0
ответ дан 3 December 2019 в 01:53
поделиться