Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700

Память освобождается, но значение остается

03.03.2016, 20:53. Показов 4069. Ответов 78
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Почему в следующем коде, программа завершается принудительно, но в консоли все равно видно значение переменной, память которой была удалена?
Откуда берется это значение?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int* getIntegerFromHeap()
{
    int *x = new int(20);
    return x;
}
 
int main()
{
    int *x = getIntegerFromHeap();
    cout << *x << std::endl;
    delete x;
    cout << *x;//выводит в консоль 20 и программа аварийно завершается 
    return 0;
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
03.03.2016, 20:53
Ответы с готовыми решениями:

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

Освобождается ли память?
Под вводимое с клавиатуры количество переменных выделяется память. Затем переменным в цикле присваивается значение. int units, *x; ...

Память освобождается не полностью
Суть такова. При многократном выделении/освобождении растет (судя по диспетчеру задач Шindows) используемая программой память. Например,...

78
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
03.03.2016, 22:10
Студворк — интернет-сервис помощи студентам
А этого у вас нет из-за того, что:
Цитата Сообщение от castaway Посмотреть сообщение
оператор delete не изменяет значение указателя.
Добавлено через 1 минуту
Цитата Сообщение от Sabnik18 Посмотреть сообщение
Насколько я понял, если вы освободили память, то при выделении памяти под следующую переменную используется та, которая была освобождена до этого.
Далеко не факт. Всё зависит от аллокатора и размера выделяемой памяти.
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
03.03.2016, 22:11  [ТС]
Цитата Сообщение от castaway Посмотреть сообщение
Память помечена "свободной". Откуда может взяться утечка?
Цитата Сообщение от castaway Посмотреть сообщение
Память была "помечена" свободной, что не принуждает данную процедуру очищать предыдущее значение.
Вы же сами сказали, что значение может быть не удалено. Не адрес сказали, а именно значение. Если есть значение, значит есть и память, в которой оно хранится.

TheCalligrapher,
Это я понимаю, но мне интересно, кто и по каким критериям выбирает что именно этот участок(прежде занятый),
должен быть занят новыми данными?
0
93 / 6 / 5
Регистрация: 25.02.2016
Сообщений: 30
03.03.2016, 22:11
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
 
int* getIntegerFromHeap()
{
    int *x = new int(20);
    return x;
}
 
void f()
{
    int *x = getIntegerFromHeap();
    std::cout << *x << std::endl;
    delete x; // можно и не делать
}
 
int main()
{
    f();
 
    // чистый стек
    return 0;
}
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13239 / 6871 / 1827
Регистрация: 18.10.2014
Сообщений: 17,417
03.03.2016, 22:13
Цитата Сообщение от sys_beginner Посмотреть сообщение
Это я понимаю, но мне интересно, кто и по каким критериям выбирает что именно этот участок(прежде занятый),
должен быть занят новыми данными?
Это уже зависит от алгоритма работы аллокатора в библиотеке времени выполнения (или, через посредство библиотеки времени выполнения, в ОС), каковых есть великое множество. Никаких "стандартных" и "общеизвестных" критериев тут нет.

Но вы можете, например, попробовать сразу выделить еще один 'int' и посмотреть, ляжет ли он на место предыдущего освобожденного 'int' или куда-то еще. Пробовали? Лег?
1
93 / 6 / 5
Регистрация: 25.02.2016
Сообщений: 30
03.03.2016, 22:14
Цитата Сообщение от sys_beginner Посмотреть сообщение
что именно этот участок(прежде занятый),
должен быть занят новыми данными?
подсистема управления памятью Опер. системы.
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
03.03.2016, 22:15
Цитата Сообщение от sys_beginner Посмотреть сообщение
Вы же сами сказали, что значение может быть не удалено. Не адрес сказали, а именно значение. Если есть значение, значит есть и память, в которой оно хранится.
Значение нельзя удалить. Его можно "затереть" другим. Мои высказывания не противоречат друг другу.
0
93 / 6 / 5
Регистрация: 25.02.2016
Сообщений: 30
03.03.2016, 22:17
Цитата Сообщение от sys_beginner Посмотреть сообщение
Если есть значение, значит есть и память, в которой оно хранится.
эта память после delet принадлежит не Вашему потоку выполнения. Вы ресурс захватили, Вы его освободили. Дальше его захватит ещё кто-то. (например диспетчер памяти ОС).
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13239 / 6871 / 1827
Регистрация: 18.10.2014
Сообщений: 17,417
03.03.2016, 22:20
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Но вы можете, например, попробовать сразу выделить еще один 'int' и посмотреть, ляжет ли он на место предыдущего освобожденного 'int' или куда-то еще.
Например, мой эксперимент в MSVC

C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
 
int main()
{
    int *x = new int(20);
    std::cout << x << " " << *x << std::endl;
    delete x;
 
    x = new int(40);
    std::cout << x << " " << *x << std::endl;
    delete x;
}
дает

009ABC58 20
009ABC58 40
Т.е. следующий 'int' лег на место предыдущего.

Но в любом случае это все - непредсказуемые детали реализации. Может лечь, может не лечь... Какая вам-то разница?
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
03.03.2016, 22:27
Цитата Сообщение от sys_beginner Посмотреть сообщение
Вы же сами сказали, что значение может быть не удалено.
Я про удаление значения вообще ничего не говорил.
0
BrainOverflow
 Аватар для sab1ch
126 / 130 / 64
Регистрация: 31.03.2013
Сообщений: 556
03.03.2016, 22:32
Мне кажется эта тема потеряла смысл на 2 посте.
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
03.03.2016, 22:33  [ТС]
BlackMare,
Почему можно не писать delete? Думаю нужно, память выделенная в getIntegerFromHeap же не освободилась. Оно ведь в куче хранится, а не в стеке.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Но вы можете, например, попробовать сразу выделить еще один 'int' и посмотреть, ляжет ли он на место предыдущего освобожденного 'int' или куда-то еще. Пробовали? Лег?
Спасибо. Попробовал. Нет, не легло на место освобожденного int, занялся другой адрес
castaway,
Снова не понятно. Вы говорите, что значение остается и его нельзя удалить, а лишь затереть другим. Как?
Значит в таком случае есть/будет утечка, ибо для хранения значения требуется же память? Возможно я чего то не понимаю, но из ваших сделал такой вывод... Ниже предоставил тесты
C++
1
2
3
4
5
6
7
8
9
int main()
{
    int* x = new int(10);
    delete x;
    std::cout << &x << std::endl;//002AFB64
    int* y = new int(10);
    std::cout << &y;//002AFB58
        return 0;
}
Если адреса x и y отличаются, и значение для x сохранено, значит память утекла. Нет? Почему?
0
Неэпический
 Аватар для Croessmah
18150 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,047
Записей в блоге: 1
03.03.2016, 22:36
Цитата Сообщение от sys_beginner Посмотреть сообщение
Значит в таком случае есть/будет утечка, ибо для хранения значения требуется же память? Возможно я чего то не понимаю, но из ваших сделал такой вывод...
Вот вышел ты с баллоном краски, написал на заборе короткое слово,
потом храбро охранял его три дня. А потом ушел.
Надпись исчезла из-за этого?
Уверен, что этот забор кто-то другой не украсит теперь?
1
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
03.03.2016, 22:36
Цитата Сообщение от sys_beginner Посмотреть сообщение
Если адреса x и y отличаются, и значение для x сохранено, значит память утекла. Нет? Почему?
Что вы подразумеваете под "утечкой"?
0
93 / 6 / 5
Регистрация: 25.02.2016
Сообщений: 30
03.03.2016, 22:38
Цитата Сообщение от sys_beginner Посмотреть сообщение
Почему можно не писать delete?
я про данный конкретный случай. так как программа ничего больше не делает, то при выходе вся выделенная для
потока память все равно будет возвращена ОС.
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
03.03.2016, 22:39
Цитата Сообщение от sys_beginner Посмотреть сообщение
Ниже предоставил тесты
Тесты неверные.
Нужно смотреть не адрес указателя, а адрес в указателе:
C++
1
2
3
4
5
6
7
8
int main()
{
    int* x = new int(10);
    delete x;
    std::cout << x << std::endl;
    int* y = new int(10);
    std::cout << y;
}
1
93 / 6 / 5
Регистрация: 25.02.2016
Сообщений: 30
03.03.2016, 22:43
Цитата Сообщение от DrOffset Посмотреть сообщение
Нужно смотреть не адрес указателя, а адрес в указателе:
так точно.
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
03.03.2016, 22:46  [ТС]
Croessmah,
Не уверен, но хочу понять уверен ли компилятор и почему а так же что гласят стандарты на эту тему

Цитата Сообщение от castaway Посмотреть сообщение
Что вы подразумеваете под "утечкой"?
Когда в памяти остаются данные, которые больше не используются. То есть занимается лишнее пространство для данных которые не будут больше использованы.

DrOffset,
Все равно разные значения(адреса)
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
03.03.2016, 22:52
Цитата Сообщение от sys_beginner Посмотреть сообщение
Все равно разные значения
Ну разные и разные. Выше же писалось:
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
в любом случае это все - непредсказуемые детали реализации
Добавлено через 3 минуты
Вот тест в онлайн компиляторе vc++: http://rextester.com/POA50454 , адреса разные.
Вот тест в онлайн компиляторе clang: http://rextester.com/JHACV81511 , адреса одинаковые.
Разная реализация менеджера памяти, разные результаты.
Однако вышесказанного это не отменяет, delete помечает память свободной (менеджер памяти теперь может отдать ее по другому запросу), а не физически что-то там удаляет
Если память вернули менеджеру памяти (пометили свободной), то утечки нет.
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
03.03.2016, 22:55
Цитата Сообщение от sys_beginner Посмотреть сообщение
Когда в памяти остаются данные, которые больше не используются. То есть занимается лишнее пространство для данных которые не будут больше использованы.
Я не понимаю что вам непонятно.

Цитата Сообщение от sys_beginner Посмотреть сообщение
Если адреса x и y отличаются, и значение для x сохранено, значит память утекла. Нет? Почему?
Потому что оно не затёрлось другим значением. Причина описана в 21-м сообщении.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13239 / 6871 / 1827
Регистрация: 18.10.2014
Сообщений: 17,417
03.03.2016, 22:58
Цитата Сообщение от sys_beginner Посмотреть сообщение
Значит в таком случае есть/будет утечка, ибо для хранения значения требуется же память?
Динамическая память в типичиных реализациях стандартной библиотеки реализуется двухуровневым механизмом. На первом уровне библиотека времени выполнения запрашивает большой блок памяти у ОС. Затем, на втором уровне, реализуется ("вручную" или еще как) распределение мелких блоков памяти внутри этого большого блока. Когда заполнится первый большой блок, у ОС будет запрошен следующий большой блок и т.д. Запрос блоков памяти у ОС - операция "тяжелая", поэтом у ОС память запрашивается редко и большими блоками.

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

Когда вы сделали 'delete' для вашего 'int', библиотека времени выполнения записала в своих внутренних структурах, что это место внутри большого блока теперь свободно. Однако возвращать большой блок обратно в ОС она не стала. Этот большой блок будет использоваться для дальнейших выделений памяти и возвращать его ОС (чтобы потом обратно запрашивать) нет смысла - это слишком "тяжелая" операция.

Поэтому с точки зрения ОС этот большой блок остается выделенным. И данные в нем ОС продолжает тупо честно хранить. Библиотека же времени выполнения знает, что место, занимавшееся вашим 'int' в большом блоке свободно и, рано или поздно, библиотека времени выполнения использует его для хранения чего-то другого.

Пока библиотека времени выполнения помнит, что есть такое место, оставленное после себя вашим освобожденным 'int', никакой утечки разумеется нет.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
03.03.2016, 22:58

Почему память массива не освобождается?
В выводе *b должна быть ересь, но на самом деле коректно выводит цифру &quot;3&quot;. #include &lt;iostream&gt; using namespace std; void...

Не освобождается память при выбросе исключений
это у меня находится в классе Add. Туда я добавляю элементы, перед этим проверяю, нет ли такого уже: try { ...

Правильно ли в данной программе освобождается память?
Доброго времени суток, написал учебную программу из книги Праты. В принципе задание не требует всего этого, но решил понабить руку и...

Не освобождается память в списке указателей на класс
#include &lt;iostream&gt; #include &lt;list&gt; using namespace std; class myClass{ private: int x; bool life; public: ...

Освобождается ли память выделенная под массив после вызова деструктора класса
Здравствуйте, изучаю ООП, вот у меня такой вопрос, вот мой код: #include &lt;iostream&gt; using namespace std; class myclass { ...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Книги по геймдизайну, левел-дизайну, игровым механикам и проектированию игрового опыта
8Observer8 08.11.2026
Содержание блога | English Version 1. 2003 - 06 - Designing Virtual Worlds (1st Edition) Автор: Richard A. Bartle | Объем: 768 стр. Ссылки: Amazon . . .
Родители токсичные абьюзеры по отношению к своим детям ругают их оскорбляют не любят
zorxor 08.11.2026
Жить в атмосфере постоянных оскорблений, критики и холодности со стороны родителей — это тяжелое и болезненное испытание, которое оставляет глубокие эмоциональные раны. Токсичное и абьюзивное. . .
Как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Ответ от Джемени ИИ.
zorxor 08.11.2026
Джемени, как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Многие люди, возвращаясь домой, сразу переодеваются в максимально свободную одежду или вовсе предпочитают. . .
Паттерн очереди действий/команд (Action / Command Queue). Система очереди действий и кат-сцен с SDL3 Callbacks, cglm и OpenGL
8Observer8 07.11.2026
Содержание блога | English Version Руководство для начинающих по реализации паттерна очереди действий/ команд (Action / Command Queue) на C++ (C++20) с использованием официального SDL3 Callbacks. . .
Проверка полного ФИО в типовом справочнике
Maks 07.11.2026
Решение реализовано в конфигурации КА2, на примере справочника "КонтактныеЛицаПартнеров". Задача: Запрет инициалов. Не допускаеть использование сокращений вида "И. И. ", "И. И. ", "И И" и. . .
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . . Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг. Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует. В процессе разработки. . .
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru