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

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

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

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

18.05.2013, 03:56. Просмотров 2708. Ответов 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; }

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

delete[] *pointer vs. delete pointer и утечка памяти - C++
Здравствуйте! Есть класс "умного" указателя counted_ptr, который удаляет хранящийся в нём T* owned; только если кол-во владельцев...

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

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

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
alkagolik
Заблокирован
20.05.2013, 01:29 #16
точнее "делают вид что понимают"
Убежденный
Системный программист
Эксперт С++
15503 / 7001 / 1105
Регистрация: 02.05.2013
Сообщений: 11,435
Завершенные тесты: 1
20.05.2013, 01:48 #17
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от alkagolik Посмотреть сообщение
шо за ересь? "статическая память"... какой наркоман это сформулировал?
C++, Стандарт-2003:
3.7 Storage duration

1. Storage duration is the property of an object that defines the minimum potential
lifetime of the storage con-taining the object. The storage duration is determined by
the construct used to create the object and is one of the following:

- static storage duration
- automatic storage duration
- dynamic storage duration
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
20.05.2013, 02:23 #18
Убежденный,
Цитата Сообщение от Убежденный Посмотреть сообщение
static storage duration
Вы не заметили слова duration? Есть понятие статический класс памяти, статический объект/переменная, но никак не "статическая память". Про классы памяти уделяют достаточно внимания в более или менее приличных книгах. Автор видать пропустил тему, раз задается подобным, немного несуразным, вопросом.
Tulosba
20.05.2013, 10:36
  #19

Не по теме:

Цитата Сообщение от Toshkarik Посмотреть сообщение
статическая память
ну это ж SRAM, та что на триггерах

faridenco
0 / 0 / 0
Регистрация: 08.02.2013
Сообщений: 26
20.05.2013, 19:56  [ТС] #20
Цитата Сообщение от Toshkarik Посмотреть сообщение
Убежденный,

Вы не заметили слова duration? Есть понятие статический класс памяти, статический объект/переменная, но никак не "статическая память". Про классы памяти уделяют достаточно внимания в более или менее приличных книгах. Автор видать пропустил тему, раз задается подобным, немного несуразным, вопросом.
Значит тогда "динамической памяти" тоже нету. Однако везде этот термин употребляют. Потому что так короче и удобней, умник.

Вопрос совсем не несуразный. Раз на него до сих пор не ответили. Поначалу писали что это ошибка, а оказалось что стандарт это не определяет как ошибку. Ну и раз стандарт это определяет как undefined поведение, то остается в силе мой вопрос об обработке этой ситуации компиляторами, в частности компилятором Microsoft.

Впрочем я итак знаю, что программа, скомпилированная компилятором Microsoft, ничего не делает когда встречает delete[] по отношению к статической памяти. Потому что я ни разу не видел, чтобы программы мои падали.
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
20.05.2013, 20:17 #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, он не соответствует стандарту. Не нужно рассчитывать в этом случае на компилятор, в следующей версии поведение может кардинально измениться.
Убежденный
Системный программист
Эксперт С++
15503 / 7001 / 1105
Регистрация: 02.05.2013
Сообщений: 11,435
Завершенные тесты: 1
20.05.2013, 20:18 #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  [ТС] #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.
Убежденный
Системный программист
Эксперт С++
15503 / 7001 / 1105
Регистрация: 02.05.2013
Сообщений: 11,435
Завершенные тесты: 1
20.05.2013, 20:52 #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  [ТС] #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 минут
И в релизе тоже разумеется у меня ошибок нет.
Убежденный
Системный программист
Эксперт С++
15503 / 7001 / 1105
Регистрация: 02.05.2013
Сообщений: 11,435
Завершенные тесты: 1
20.05.2013, 21:29 #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  [ТС] #27
Да, я осведомлен о smart-pointer-х. Просто ищу способы как обходится без них.
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
20.05.2013, 21:36 #28
Убежденный, зачем здесь delete для массива?
Убежденный
Системный программист
Эксперт С++
15503 / 7001 / 1105
Регистрация: 02.05.2013
Сообщений: 11,435
Завершенные тесты: 1
20.05.2013, 21:42 #29
Цитата Сообщение от alsav22 Посмотреть сообщение
Убежденный, зачем здесь delete для массива?
"Здесь" - это где именно ?
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
20.05.2013, 21:47 #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;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.05.2013, 21:47
Привет! Вот еще темы с ответами:

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
20.05.2013, 21:47
Ответ Создать тему
Опции темы

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