Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 20, средняя оценка - 5.00
faridenco
0 / 0 / 0
Регистрация: 08.02.2013
Сообщений: 26
#1

delete[] статической памяти - C++

18.05.2013, 03:56. Просмотров 2647. Ответов 45
Метки нет (Все метки)

1. Должна ли возникать ошибка (или падение программы) при применении delete[] к статической памяти? У меня (Microsoft Visual Studio 2005) никаких ошибок не возникает. Но, просто, сталкивался с тем, что на некой 64-х разрядной машине (Windows), при запуске моей 32-х разрядной программы (то есть в эмуляторе) она вылетала в месте где используется delete[] к статической переменной. А также встречал в интернете вопросы о ошибке при delete[] статической памяти, но там не указывался компилятор.

2. Если вылетание при delete[] статической памяти возможно, то как узнать какой указатель: на динамическую память или статическую. Теоретически мне это не предсnавляется сложным. Если этого нету в C/C++, то может такая возможность есть в WinApi?
Вот, например, есть в функция в которую передается char*. И эта память освобождается в функции. Но в функцию ведь может быть передана и константа и указатель на статическую память.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.05.2013, 03:56     delete[] статической памяти
Посмотрите здесь:

Переменные в статической и динамической памяти! - C++
Народ, подскажите как этот рисунок перевести в программу! тоесть как с помощью программы разместить таким образом переменные в памяти

Выделение статической памяти, не используя статические объекты - C++
Здравствуйте! Как известно, когда мы объявляем статическую переменную, то компилятор выделяет ей место с самого начала, т. е....

Возможно ли обращение к статической памяти функции извне? - C++
Здравствуйте! Возможно ли сделать так? Obj* ptr; void F() { static Obj _obj = { }; ptr = &_obj; }

Delete[] и утечка памяти - C++
Как можно избежать вытока памяти? И вообще почкму криво работает? #include<iostream> #include<windows.h> #include<ctime> using...

Освобождение памяти delete - C++
Если у меня есть указатель (pt) N-ой степени, я присвоил ему указатель на начало массива (N - 1)ой степени (через new), затем некоторому...

Утечка памяти и delete - C++
Вот накопились вопросы про утечки памяти. 1) Как проявляется утечка памяти? На многих сайтах написано что если не удалять указатели то...

Очистка памяти delete[]; - C++
Есть функция ввида: void loltest(int md3) { char* randChars; int cCount; if(md3 <= 0) cCount = 13; ...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Toshkarik
1139 / 856 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
20.05.2013, 20:17     delete[] статической памяти #21
Цитата Сообщение от faridenco Посмотреть сообщение
Потому что так короче и удобней, умник.
Держите свои эмоции при себе, не переходите на личности.
Не ответили на вопрос потому что ответ на него есть в любой более или менее приличной книге по C++ для начинающих. В частности говорится о том, что память под статические объекты выделяется при запуске программы, и освобождается при ее завершении, никакие delete ее не освободят.
http://en.wikipedia.org/wiki/Data_segment
A data segment is a portion of virtual address space of a program, which contains the global variables and static variables that are initialized by the programmer. The size of this segment is determined by the values placed there by the programmer before the program was compiled or assembled, and does not change at run-time.
Добавлено через 2 минуты
Цитата Сообщение от faridenco Посмотреть сообщение
Поначалу писали что это ошибка, а оказалось что стандарт это не определяет как ошибку.
Смотря что подразумевать под ошибкой. Данный код ошибочен, так как это чистый UB, он не соответствует стандарту. Не нужно рассчитывать в этом случае на компилятор, в следующей версии поведение может кардинально измениться.
Убежденный
Системный программист
Эксперт С++
15248 / 6880 / 1092
Регистрация: 02.05.2013
Сообщений: 11,261
Завершенные тесты: 1
20.05.2013, 20:18     delete[] статической памяти #22
Цитата Сообщение от faridenco Посмотреть сообщение
Поначалу писали что это ошибка, а оказалось что стандарт это не определяет как ошибку.
Стандартом это квалифицируется, как неопределенное поведение (undefined behavior, UB).
Разве этого не достаточно ?

Цитата Сообщение от faridenco Посмотреть сообщение
Впрочем я итак знаю, что программа, скомпилированная компилятором Microsoft, ничего не делает когда встречает delete[] по отношению к статической памяти.
Это не так.
Попробуйте, например, вызвать "operator delete []" на адресе
какой-нибудь статической или глобальной переменной.
Скорее всего, получите разрушение кучи (heap corruption).
faridenco
0 / 0 / 0
Регистрация: 08.02.2013
Сообщений: 26
20.05.2013, 20:39  [ТС]     delete[] статической памяти #23
Цитата Сообщение от Toshkarik Посмотреть сообщение
Держите свои эмоции при себе, не переходите на личности.
Не ответили на вопрос потому что ответ на него есть в любой более или менее приличной книге по C++ для начинающих. В частности говорится о том, что память под статические объекты выделяется при запуске программы, и освобождается при ее завершении, никакие delete ее не освободят.
http://en.wikipedia.org/wiki/Data_segment


Добавлено через 2 минуты

Смотря что подразумевать под ошибкой. Данный код ошибочен, так как это чистый UB, он не соответствует стандарту. Не нужно рассчитывать в этом случае на компилятор, в следующей версии поведение может кардинально измениться.
Я прекрасно осведомлен как устроена память, как она выделяется и освобождается. Я знаю, что delete[] не освобождает статическую и автоматическую память. Вопрос мой совсем был не об этом. Перечитай мои сообщения.

Добавлено через 9 минут
Цитата Сообщение от Убежденный Посмотреть сообщение
Попробуйте, например, вызвать "operator delete []" на адресе
какой-нибудь статической или глобальной переменной.
Скорее всего, получите разрушение кучи (heap corruption).
Я еще в первом посте написал, что в реализациях от Micrsoft я такого не замечал. Я указал свой компилятор. Что мне пробовать, когда я так везде пишу на своем компиляторе, еще ни одна программа не вылетала. Падала только при запуске на эмуляторе, в 64-х битной винде (32-х битная программа). Впроем и о этом я уже писал.

Добавлено через 7 минут
Стандартом это квалифицируется, как неопределенное поведение (undefined behavior, UB).
Это означает, что стандартом поведение не определено, а не то что поведение программы непредсказуемо ). Это означает, что разработчик компилятор сам решает как обработать эту ситуацию. То есть все зависит от реализации.
Вот пример я уже привел. В реализации от Microsoft ничего не делается. Куча повреждается если пишешь в динамическую память по адресу, не выделенному оператором new.
Убежденный
Системный программист
Эксперт С++
15248 / 6880 / 1092
Регистрация: 02.05.2013
Сообщений: 11,261
Завершенные тесты: 1
20.05.2013, 20:52     delete[] статической памяти #24
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
 
int value = 123;
 
int main()
{
    delete [] &value;
    std::cout << value << std::endl;
    return 0;
}
Отладочная версия вылетает с сообщением "Debug Assertion Failed (_BLOCK_TYPE_IS_VALID).
Релизная версия вылетает с исключением 0xC0000374 (Heap Corruption).
Проверил на VC++ 2008/2010/2012.
faridenco
0 / 0 / 0
Регистрация: 08.02.2013
Сообщений: 26
20.05.2013, 21:05  [ТС]     delete[] статической памяти #25
Цитата Сообщение от Убежденный Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
 
int value = 123;
 
int main()
{
    delete [] &value;
    std::cout << value << std::endl;
    return 0;
}
Отладочная версия вылетает с сообщением "Debug Assertion Failed (_BLOCK_TYPE_IS_VALID).
Релизная версия вылетает с исключением 0xC0000374 (Heap Corruption).
Проверил на VC++ 2008/2010/2012.
Мой компилятор (Microsoft Visual Studio 2005) в дебаге не выдал никаких ошибок. Благодарю, что вы пишите по теме. Именно это мне и было интересно узнать. То есть, на сколько Microsoft придерживается определенному правилу в своей реализации. Теперь я знаю, что в других компиляторах Microsoft будет ошибка.

Добавлено через 5 минут
И в релизе тоже разумеется у меня ошибок нет.
Убежденный
Системный программист
Эксперт С++
15248 / 6880 / 1092
Регистрация: 02.05.2013
Сообщений: 11,261
Завершенные тесты: 1
20.05.2013, 21:29     delete[] статической памяти #26
Давайте вернемся к тому, с чего начали.

Цитата Сообщение от faridenco Посмотреть сообщение
1. Должна ли возникать ошибка (или падение программы) при применении delete[] к статической памяти?
Согласно стандарту, не должна. Но указывается, что в этом случае поведение не определено.
То есть, в зависимости от комбинации "компилятор-платформа" и других факторов, может
возникнуть все, что угодно - от "замалчивания", которое наблюдается на VC++ 2005, до
выбрасывания исключений и порчи данных.

Добавлю, что delete-выражение корректно только тогда, когда ему передается не только
правильное значение указателя, но и его тип:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
 
 
 
class foo
{
public:
    foo()
    {
        std::cout << "create" << std::endl;
    }
 
    ~foo()
    {
        std::cout << "destroy" << std::endl;
    }
};
 
 
 
foo *create_foo()
{
    return (new foo());
}
 
void destroy_foo(void *pFoo)
{
    delete pFoo;
}
 
 
 
int main()
{
    foo *pFoo = create_foo();
    destroy_foo(pFoo);
    return 0;
}
Вывод данной программы (VC++ 2012):
> create
Как видим, деструктор foo не был вызван.
Кстати, не удивляйтесь, если на каком-то компиляторе эта программа завершится с ошибкой
или повиснет, так как это тоже undefined behavior.

И я могу объяснить, почему Стандартом здесь не предусмотрен выброс какого-нибудь исключения,
что было бы благом. Причина - оптимизация. Указатели хранят лишь адрес ячейки памяти, без
информации о типах и тому подобного. Подразумевается, что программист сам следит за
правильным удалением объектов и "не платит за то, что не использует".

Цитата Сообщение от faridenco Посмотреть сообщение
2. Если вылетание при delete[] статической памяти возможно, то как узнать какой указатель: на динамическую память или статическую.
Никак.
Этот вопрос решается на другом уровне - "политика владения".
Обычно на уровне всего исходного кода проекта поддерживается ряд ограничений по поводу
того, какие функции могут создавать и удалять объекты, а какие нет.
Например, функция, принимающая указатель, обычно не освобождает его, оставляя это на
совести вызывающего кода. Это один из простейших паттернов владения объектами.
Кроме этого, вместо "голых" указателей надежнее применять смарт-поинтеры и программные
интерфейсы, самостоятельно реализующие управление временем жизни объектов. Например,
подсчет ссылок. Это очень распостраненный подход на C++, где есть такие вещи, как RAII.
Количество ошибок, связанных с управлением памятью, при таком подходе сильно снижается.
faridenco
0 / 0 / 0
Регистрация: 08.02.2013
Сообщений: 26
20.05.2013, 21:36  [ТС]     delete[] статической памяти #27
Да, я осведомлен о smart-pointer-х. Просто ищу способы как обходится без них.
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
20.05.2013, 21:36     delete[] статической памяти #28
Убежденный, зачем здесь delete для массива?
Убежденный
Системный программист
Эксперт С++
15248 / 6880 / 1092
Регистрация: 02.05.2013
Сообщений: 11,261
Завершенные тесты: 1
20.05.2013, 21:42     delete[] статической памяти #29
Цитата Сообщение от alsav22 Посмотреть сообщение
Убежденный, зачем здесь delete для массива?
"Здесь" - это где именно ?
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
20.05.2013, 21:47     delete[] статической памяти #30
Цитата Сообщение от Убежденный Посмотреть сообщение
"Здесь" - это где именно ?
C++
1
2
3
4
5
6
7
8
9
10
11
 
#include <iostream>
 
int value = 123;
 
int main()
{
    delete [] &value;
    std::cout << value << std::endl;
    return 0;
}
Убежденный
Системный программист
Эксперт С++
15248 / 6880 / 1092
Регистрация: 02.05.2013
Сообщений: 11,261
Завершенные тесты: 1
20.05.2013, 21:50     delete[] статической памяти #31
Взято из вопроса топикстартера:

Цитата Сообщение от faridenco Посмотреть сообщение
1. Должна ли возникать ошибка (или падение программы) при применении delete[] к статической памяти?
daslex
1271 / 516 / 106
Регистрация: 02.08.2011
Сообщений: 2,662
20.05.2013, 22:15     delete[] статической памяти #32
Цитата Сообщение от faridenco Посмотреть сообщение
Значит тогда "динамической памяти" тоже нету
Динамической нету. Есть динамически распределяемая, которая распределяется на что-то, сама память не расширяется, сколько она вмещает, столько и будет вмещать, больше в нее не засунешь.

Не по теме:

и вообще раздули из мухи слона

faridenco
0 / 0 / 0
Регистрация: 08.02.2013
Сообщений: 26
20.05.2013, 23:35  [ТС]     delete[] статической памяти #33
Цитата Сообщение от daslex Посмотреть сообщение
Динамической нету. Есть динамически распределяемая, которая распределяется на что-то, сама память не расширяется, сколько она вмещает, столько и будет вмещать, больше в нее не засунешь.

Не по теме:

и вообще раздули из мухи слона

Это был риторический вопрос. Термин "динамическая память" употребляется к языкам програмирования. А на твою писанину для дедсада мне наплевать.
daslex
1271 / 516 / 106
Регистрация: 02.08.2011
Сообщений: 2,662
20.05.2013, 23:38     delete[] статической памяти #34
faridenco, тебе еще на первых двух страницах сказали ответ, дедуля.
faridenco
0 / 0 / 0
Регистрация: 08.02.2013
Сообщений: 26
20.05.2013, 23:44  [ТС]     delete[] статической памяти #35
Цитата Сообщение от daslex Посмотреть сообщение
faridenco, тебе еще на первых двух страницах сказали ответ, дедуля.
Советую в таком случае внимательно все перечитать.
А вообще ответ не дан до сих пор. Я спрашивал про реализации (компиляторы). Более менее имею представление о компилторах Microsoft. А об этом мне ответили на третьей странице. Ни о каких больше реализациях мне не отвечали.
Но, то что это не ошибка, а поведение зависит от реализации - это точно.
daslex
1271 / 516 / 106
Регистрация: 02.08.2011
Сообщений: 2,662
20.05.2013, 23:53     delete[] статической памяти #36
faridenco, очки надень и посмотри

Добавлено через 8 минут
Цитата Сообщение от faridenco Посмотреть сообщение
1. Должна ли возникать ошибка (или падение программы) при применении delete[] к статической памяти? У меня (Microsoft Visual Studio 2005) никаких ошибок не возникает. Но, просто, сталкивался с тем, что на некой 64-х разрядной машине (Windows), при запуске моей 32-х разрядной программы (то есть в эмуляторе) она вылетала в месте где используется delete[] к статической переменной. А также встречал в интернете вопросы о ошибке при delete[] статической памяти, но там не указывался компилятор.
2. Если вылетание при delete[] статической памяти возможно, то как узнать какой указатель: на динамическую память или статическую. Теоретически мне это не предсnавляется сложным. Если этого нету в C/C++, то может такая возможность есть в WinApi?
Вот, например, есть в функция в которую передается char*. И эта память освобождается в функции. Но в функцию ведь может быть передана и константа и указатель на статическую память.
Где?
Цитата Сообщение от faridenco Посмотреть сообщение
Я спрашивал про реализации (компиляторы)
faridenco
0 / 0 / 0
Регистрация: 08.02.2013
Сообщений: 26
20.05.2013, 23:54  [ТС]     delete[] статической памяти #37
Цитата Сообщение от daslex Посмотреть сообщение
faridenco, очки надень и посмотри
По первому посту ясно, что меня интересует поведение программы при delete[] статической памяти. И что на моем компиляторе нет ошибок. А значит нужна информация о реализациях. Ответ поведение зависит от реализации (undefined behavior) - не ответ.

На первой странице я уточнил (когда мне все еще твердили, что это ошибка).
Поэтому и спрашиваю, как на это смотрит стандарт, как это отрабатывает компилятор Microsoft и пр.
grizlik78
Эксперт С++
1904 / 1436 / 109
Регистрация: 29.05.2011
Сообщений: 2,990
21.05.2013, 00:06     delete[] статической памяти #38
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от faridenco Посмотреть сообщение
Но, то что это не ошибка, а поведение зависит от реализации - это точно.
Поведение зависит от реализации — это implementation defined, на худой конец
unspecified behavior. А undefined behavior говорит о том, что реализации может вообще никакой не быть, то есть разработчику компилятора не стоит думать о поведении. Поведение непредсказуемо. Несколько запусков одной и той же программы могут давать разное поведение (но разумеется не обязаны).
Само использование "undefined behavior" — это и есть ошибка. Не синтаксическая, а семантическая.
daslex
1271 / 516 / 106
Регистрация: 02.08.2011
Сообщений: 2,662
21.05.2013, 00:07     delete[] статической памяти #39
Цитата Сообщение от faridenco Посмотреть сообщение
Вопрос был не только про компилятор, а про работу программы, уже скомпилированной (может ли она падать).
Цитата Сообщение от alsav22 Посмотреть сообщение
Как реагирует компилятор на такое освобождение неважно, в любом случае это ошибка.
Цитата Сообщение от Croessmah Посмотреть сообщение
На процесс компиляции это никак не повлияет - за такими вещами следит программист, а не компилятор.
Цитата Сообщение от Croessmah Посмотреть сообщение
Рано или поздно упадет, если, конечно же при компиляции Ваш код не был вырезан
Цитата Сообщение от taras atavin Посмотреть сообщение
По идее должна, так как эта же память потом будет освобождена ещё раз неявно, но винда врядли способна это гарантировать.
Вам еще на первой странице в один голос твердили, что упадет, что ошибка, что нельзя, но вы считаете себя умнее всех
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.05.2013, 00:19     delete[] статической памяти
Еще ссылки по теме:

new и delete при освобождении памяти - C++
Здравствуйте. Скажите, пожалуйста что я неправильно делаю. При освобождении памяти. Выделяем память: char **VIRTUAL = NULL; if...

Ошибка освобождения памяти new/delete - C++
При выполнении оператора deleterez вылетает ошибка BLOCK_TYPE_IS_VALID(pHead-&gt;nBlockUse) #include &lt;iostream&gt; using namespace std;...

Проверка освобождения памяти (new, delete) - C++
Всем привет. Программы помаленьку становятся сложнее. Появляются самодельные контейнеры внутри других самодельных контейнеров внутри...

почему не delete (выделение памяти) - C++
почему в примерах в мсдне не высвобождается память после использования asctime, ctime? #include &lt;time.h&gt; #include &lt;stdio.h&gt; int...

Сколько памяти освобождает delete - C++
История такая, перегрузил операторы new и delete. Теперь хочу отслеживать сколько память выделено и сколько освобождено. С выделением,...


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

Или воспользуйтесь поиском по форуму:
faridenco
0 / 0 / 0
Регистрация: 08.02.2013
Сообщений: 26
21.05.2013, 00:19  [ТС]     delete[] статической памяти #40
daslex, ЭТО НЕ ОШИБКА. Перечитай всю ветку и не тормози (или хотя бы мои сообщения).

Добавлено через 6 минут
Само использование "undefined behavior" — это и есть ошибка
Это означает, что поведение стандартом не определено.
И в этой ветке приводили примеры, когда один и тот же код с delete[] или вызывал оишбку или нет, в зависимости от реализации. Хотя по стандарту undefined behavior.
Есть величины размеры которых зависят от реализации, к ним употребляется термин implementation defined.
Yandex
Объявления
21.05.2013, 00:19     delete[] статической памяти
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru