Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
0 / 0 / 0
Регистрация: 28.06.2019
Сообщений: 6

Операция delete[] не до конца удаляет динамический массив?

19.12.2023, 22:18. Показов 1798. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Только учусь программировать. Поэтому такой вопрос: вот следующий код, в строке 19, когда компилятор выводит удаленный массив на экран (просто для интереса, что будет), последнее значение равно последнему значению массива до удаления. Что это, совпадение? Я компилировала несколько раз, с разным количеством значений массива (n) и всегда, значения, которые n>=5 удаленного массива равнялись значениям массива до удаления. Это значит что операция delete[] удаляет только первые 4 значения массива. У всех так? Если да, то почему? Это же утечка памяти. Если нет, то может дело в компиляторе или в архитектуре процессора или еще в чем-то?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <cstdlib>
#include <ctime>
 
using namespace std;
 
int main()
{
    srand(time(0));
    int n=5;
    int *mas=new int[n];
    for(int i=0; i<n; ++i)
    {
        mas[i]=rand();
        cout << mas[i] <<" ";
    }
    cout << endl;
    delete[] mas;
    for(int i=0; i<n; ++i) cout << mas[i] << " ";
}
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
19.12.2023, 22:18
Ответы с готовыми решениями:

Динамический массив и delete
Всегда учили писать в конце программы delete(массив) в случаи если он динамический, но в последние время стал замечать наглецов которые так...

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

Динамический массив.операция new(Си или Си++?)
Здравствуйте! Операция new для выделения динамической памяти используется в Си? Компилятор выдает ошибки. Может необходимо библиотеку...

24
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12925 / 6793 / 1819
Регистрация: 18.10.2014
Сообщений: 17,190
19.12.2023, 22:22
Цитата Сообщение от A1ena Посмотреть сообщение
Это значит что операция delete[] удаляет только первые 4 значения массива.
??? Что по-вашему означает слова "удаляет"? Выжигает черную дыру в памяти компьютера, с образованием облака черного дыма? Почему вы ожидаете, что данные в "удаленной" области памяти должны как-то поменяться? Откуда возникли такие ожидания?

В любом случае, вам не разрешается осуществлять доступ к памяти после delete[], поэтому вопросы того, что там хранится или поменялось ли там что-то, вас волновать не должны. Строка 19 вашего кода имеет неопределенное поведение. Что бы она там ни делала - это ничего не значит.

Цитата Сообщение от A1ena Посмотреть сообщение
удаляет только первые 4 значения массива.
Почему вы решили, что первые 4 значения "удалились", если, как вы сами сказали, они на самом деле просто поменялись на другие значения? Еще раз: что по вашему значит слово "удалять"?

Цитата Сообщение от A1ena Посмотреть сообщение
Это же утечка памяти.
С чего бы это вдруг?
1
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
19.12.2023, 22:26
Лучший ответ Сообщение было отмечено A1ena как решение

Решение

Цитата Сообщение от A1ena Посмотреть сообщение
совпадение?
В некотором роде)
Когда вы удаляете память, то она физически не уничтожается. Она просто помечается свободной, и может отдана кому-то ещё, и быть перезаписана. Но это не обязательно происходит сразу же. Какое то время память может содержать старые значения, которые были до удаления.
1
0 / 0 / 0
Регистрация: 28.06.2019
Сообщений: 6
19.12.2023, 22:29  [ТС]
хорошо, я могу неправильно понимать значение "утечка памяти". В моем понимании, что операция delete[] удаляет значения массива, чтобы не было утечки памяти, если этот массив больше не нужен. Задам вопрос по-другому. Почему после удаления, первые 4 значения удаленного массива не равны первым 4 значениям массива до удаления, а после 4 значения, все равны?
0
фрилансер
 Аватар для Алексей1153
6444 / 5637 / 1128
Регистрация: 11.10.2019
Сообщений: 14,993
19.12.2023, 22:34
Цитата Сообщение от A1ena Посмотреть сообщение
Почему после удаления
неопределённое поведение же
1
0 / 0 / 0
Регистрация: 28.06.2019
Сообщений: 6
19.12.2023, 22:35  [ТС]
TheCalligrapher,
хорошо, я могу неправильно понимать значение "утечка памяти". В моем понимании, что операция delete[] удаляет значения массива, хрянящиеся по адресу указателя и удаляет сам указатель.
Задам вопрос по-другому. Почему после удаления, первые 4 значения удаленного массива не равны первым 4 значениям массива до удаления, а после 4 значения, все равны?
0
38 / 27 / 13
Регистрация: 18.12.2023
Сообщений: 74
19.12.2023, 22:44
A1ena, Нет фиксированного объяснения почему имеено после 4 значения, может быть много причин, от архитектуры процессора до оптимизации компилятора.
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12925 / 6793 / 1819
Регистрация: 18.10.2014
Сообщений: 17,190
19.12.2023, 23:02
Цитата Сообщение от A1ena Посмотреть сообщение
В моем понимании, что операция delete[] удаляет значения массива, чтобы не было утечки памяти, если этот массив больше не нужен. Задам вопрос по-другому. Почему после удаления, первые 4 значения удаленного массива не равны первым 4 значениям массива до удаления, а после 4 значения, все равны?
"Удаляет" - значить каким-то образом помечает память как свободную для дальнейшего использования. Пока это "дальнейшее использование" не наступит, нет никакой причины как-то менять данные в "удаленной" памяти. Ваши старые данные будут продолжать лежать в этой памяти, пока их кто-то не перезапишет.

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

При желании, вы можете почитать литературу по внутреннему устройству популярных механизмов динамического распределения памяти. Там вы найдете и объяснение того, почему поменялись начальные байты. Но к языку С++ это прямого отношения не имеет.

Цитата Сообщение от A1ena Посмотреть сообщение
В моем понимании, что операция delete[] удаляет значения массива, хрянящиеся по адресу указателя и удаляет сам указатель.
"и удаляет сам указатель"? Это уже совсем не верно. С самим указателем операция delete[] ничего не делает вообще. Операция delete[] лишь удаляет массив, на начало которого указывал указатель. Вот и все. Указатель после этого становится "неопределенным", но это лишь побочный эффект уничтожения массива. Операция delete[] напрямую ничего с указателем не делает и не может делать. Она не "удаляет сам указатель". Это - бессмыслица.
1
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6130 / 2825 / 1038
Регистрация: 01.06.2021
Сообщений: 10,300
19.12.2023, 23:06
TheCalligrapher, у меня вообще все элементы остаются после удаления... хотя, компилятор предупреждает, что я использую освобожденный из памяти объект.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
19.12.2023, 23:06
Цитата Сообщение от A1ena Посмотреть сообщение
. В моем понимании, что операция delete[] удаляет значения массива
Нет. Операция delete[] делает следующее:
1) Разрушает объект, на который указывает указатель (в данном случае объект - это массив, а значит разрушение массива повлечет за собой разрушение его элементов);
2) Освобождает память, выделенную для массива.
*) Сам указатель никто не трогает, однако значение адреса, которое он содержит, перестает быть корректным и его больше нельзя использовать.

Теперь нужно разобраться что значит
1) Разрушает;
2) Освобождает.

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

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

В общем, резюмируя, вы видите старые значения, потому что текущая реализация благосклонно относится к подобного рода "хакам". Разрушение объекта в вашем случае не влияет "физически" на его содержимое, а освобождение памяти не обязано менять содержимое возвращенной памяти (и часто на практике, пока память не отдана новому запросу, это содержимое там сохранится). В то же время частичное изменение значений может быть связано как со спецификой работы вашего менеджера памяти (например в отладочном режиме), так и с возможным частичным занятием того возвращенного участка чем-то еще.
Но с точки зрения языка вы не можете смотреть освобожденную память и получать доступ к разрушенным объектам, если вы допустиили это в своей программе (намеренно или случайно), то ввеели программу в состояние неопределенного поведения, где любые гарантии работоспособности данные языком, не действуют. Любые полученные результаты ничего не значат, и никаких глобальных выводов на их основе делать нельзя.
1
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6130 / 2825 / 1038
Регистрация: 01.06.2021
Сообщений: 10,300
19.12.2023, 23:07
DrOffset, а в чем смысл, когда люди после delete или delete[] присваивают указателю nullptr?
0
0 / 0 / 0
Регистрация: 28.06.2019
Сообщений: 6
19.12.2023, 23:08  [ТС]
TheCalligrapher, спасибо. это будет следующий этап, сначала мне нужно изучить синтаксис с++. Теперь я поняла, как работает delete[]. Он не удаляет, а помечает область памяти как свободную
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
19.12.2023, 23:09
Цитата Сообщение от Royal_X Посмотреть сообщение
а в чем смысл, когда люди после delete или delete[] присваивают указателю nullptr?
Ну, очевидно, чтобы получить валидный указатель, со значением nullptr.
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6130 / 2825 / 1038
Регистрация: 01.06.2021
Сообщений: 10,300
19.12.2023, 23:10
Цитата Сообщение от DrOffset Посмотреть сообщение
чтобы получить валидный указатель, со значением nullptr.
типа, чтобы проверять его потом?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12925 / 6793 / 1819
Регистрация: 18.10.2014
Сообщений: 17,190
19.12.2023, 23:12
Цитата Сообщение от Royal_X Посмотреть сообщение
а в чем смысл, когда люди после delete или delete[] присваивают указателю nullptr?
Ну, например, затем чтобы потом где-то проверить if (указатель == nullptr). Или затем, чтобы если где-то ниже есть еще один delete[] на этот указатель, не получилось "двойного удаления". Можно придумать много причин...
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6130 / 2825 / 1038
Регистрация: 01.06.2021
Сообщений: 10,300
19.12.2023, 23:17
TheCalligrapher, т.е. после delete у нас dangling pointer. Как только мы присваиваем nullptr, то снова он валидный указатель и с ним можно работать?

DrOffset, это говнокод? имею в виду, на что указывает указатель после выхода из области видимости?

C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
int main()
{
    int* x = nullptr;
    {
        int y = 0;
        x = &y;
    }
    delete x; // так можно? или нужно было это делать выше?
}
0
0 / 0 / 0
Регистрация: 28.06.2019
Сообщений: 6
19.12.2023, 23:18  [ТС]
DrOffset, спасибо за такой развернутый ответ
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
19.12.2023, 23:20
Цитата Сообщение от Royal_X Посмотреть сообщение
это говнокод?
Без контекста? Нет. Т.е. неизвестно.
Однако значение x после block-scope использовать нельзя - это факт.

Добавлено через 1 минуту
Цитата Сообщение от Royal_X Посмотреть сообщение
delete x; // так можно?
Нет, конечно.
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6130 / 2825 / 1038
Регистрация: 01.06.2021
Сообщений: 10,300
19.12.2023, 23:22
Цитата Сообщение от DrOffset Посмотреть сообщение
после block-scope использовать нельзя - это факт.
а delete x; можно?

Добавлено через 48 секунд
Цитата Сообщение от DrOffset Посмотреть сообщение
Нет, конечно.
а как его снова сделать валидным, не трогая block-scope? типа присвоить nullptr?
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
19.12.2023, 23:22
Цитата Сообщение от Royal_X Посмотреть сообщение
а delete x; можно?
Нельзя. Значение x же изменилось в block-scope.

Добавлено через 30 секунд
Цитата Сообщение от Royal_X Посмотреть сообщение
а как его снова сделать валидным, не трогая block-scope?
C++
1
2
3
4
5
6
7
8
9
10
int main()
{
    int* x = nullptr;
    {
        int y = 0;
        x = &y;
    }
    x = nullptr;
    delete x;
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.12.2023, 23:22
Помогаю со студенческими работами здесь

Динамический одномерный массив, запоминать до конца ввода
Здравствуйте, уважаемые программисты! Как сделать, чтобы вводимые символы запоминались до нажатия клавиши &quot;Enter&quot;???(массив...

Динамический массив структур. Почему данные доступны после выполнения операции delete []
Всем привет! Выполнил вот такое задание. После того как вывелись данные трех структур, очищаю выделенную область памяти оператором delete...

Динамический двумерный массив заданного размера начала и конца
Кхм, всем привет, можно ли в дель фи реализовать данную фичу? Т.е сделать динамический массив допустим setlength(PeremenB, RaidX, RaidY);...

Операция ON DELETE
Добрый день мне нужна ваша помощь в создании БД &quot;Автосалон&quot;, хотя по сути конкретно тема не нужна тут. проблема в том что у меня...

Операция delete в векторе
Привет, друзья, делаю маленькую игрушку, там у меня постоянно появляются и уничтожаются новые объекты, и я заметил такую вещь: со временем...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru