|
|
|
Про память и delete
|
|||
|---|---|---|---|
|
#18+
Привет всем! Есть базовая структура struct Base { int a; } и порожденная struct Der : public Base { int b; } то есть никаких выделений памяти и виртуальных функций Нормально ли очистится память, если выполнить следующее: Base *b = new Der; delete b; и что будет, если выполнить такое: char *c = new double; delete c; Спасибо ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.05.2004, 16:44 |
|
||
|
Про память и delete
|
|||
|---|---|---|---|
|
#18+
1) Вообще я бы не рекомендовал этого делать (особенно если собственные операторы delete и new , про стандартные не знаю) Для этого существует виртуальный деструктор virtual ~Base() {} 2)А это вообще не скомпилируется: cannot convert from 'double *' to 'char *' И поэтому такое делать нехорошо. Хотя думаю, что стандартный delete это скушает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.05.2004, 23:01 |
|
||
|
Про память и delete
|
|||
|---|---|---|---|
|
#18+
Спасибо, Мышьяк. Во втором примере должно быть: char *c = (char*)new double; delete c; В Borland C++ 3.1 такой код не приводит к утечке памяти (coreleft() до и после совпадают) Причем все нормально даже при таком коде: char *c = (char*)new double; c=c+10; // вроде c теперь указывает вообще в другое место delete c; Что означает, что стандартный delete это "скушает" ? :) Хотелось бы по подробнее узнать о том, как работает и кушает delete и кто отвечает за пямять. И одинаков ли принцип работы delete в компиляторах C++ под DOS и Visual C++, Builder C++ под Windows Может, где статейка есть, подскажите :) Спасибо ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.05.2004, 15:11 |
|
||
|
Про память и delete
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. delete на самом деле просто освобождает область кучи для использования. после выполнения delete память не чистится (если тока деструктор не отрабатывает) и указатель остаётся "жив". (для навернячности, люди его сразу к нулю приравнивают) Таким образом, delete c+10 высвободит байт памяти, который находится на 10 от выдленного. Код: plaintext гораздо веселее вариант Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2004, 08:12 |
|
||
|
Про память и delete
|
|||
|---|---|---|---|
|
#18+
char *c = (char*)new double; c=c+10; // вроде c теперь указывает вообще в другое место delete c; Да, всё нормально. Ничего не нормально.. Высвобождать можно только тот указатель под который и была выделена память. Даже не знаю на каком у вас компиляторе c=c+10 может пройти.. Имхо, ни на каком.. для выделения памяти , new и delete оперируют функциями malloc, free.. см. msdn. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2004, 08:57 |
|
||
|
Про память и delete
|
|||
|---|---|---|---|
|
#18+
авторНичего не нормально.. Нет, кое-что нормально: Код: plaintext 1. 2. Или так: Код: plaintext 1. 2. В первом случае всё умирает нормально. Сильно в дебаге не копался, но скорее всего куча освобождает именно то число байт, которое было выделено. По кр. мере это и проще сделать и логичнее. Во втором случае, тоже всё нормально. Компилятор это съест. Ибо встречая указатель на char который c+=10; компилятор не будет лазить по коду и проверять, а не сделали ли на него new double? или валидный ли это указатель кучи :) К тому же это вообще не компилятора уже дело, это можно проверить только во время выполнения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2004, 10:41 |
|
||
|
Про память и delete
|
|||
|---|---|---|---|
|
#18+
То что умрет нормально это так.. для обычных динамических массивов любых типов можно всегда делать delete (char*) Другое дело что delete можно подсунуть указатель на объект. Тут все посложней (иногда возникает желание скастовать если отнаследован от какого-то класса скажем и т.п.).. вот тут нет. какого типа создан такой и удалять.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2004, 11:02 |
|
||
|
Про память и delete
|
|||
|---|---|---|---|
|
#18+
Теперь вроде понятно :) Получается так: За выделение и освобождение памяти отвечает ОС (сис вызовы или api). ОС каким-то образом хранит информацию о каждом выделенном блоке (начальный адрес и размер блока). Может в каких-нить таблицах... Так что системным функциям типа free(),VirtualFree() достаточно передать указатель на начало блока и освободится столько памяти, сколько было выделено под этот блок. Этот указатель может быть указателем на любой тип, даже на структуру или класс без конструктора и деструктора. Причем для массивов не обязательно ставить квадратные скобочки delete [] p; Но типы нужно точно соблюдать, когда имеем дело с классами, у которых есть конструктор и деструктор, в которых также может выделяться память. И в последнем случае очень важно ставить квадратные скобочки delete [] p; Спасибо всем! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2004, 21:20 |
|
||
|
Про память и delete
|
|||
|---|---|---|---|
|
#18+
Еще забыл добавить: если пытаться сделать delete над левым указателем (c+=10), то ОС выдаст Access Violation. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2004, 21:49 |
|
||
|
Про память и delete
|
|||
|---|---|---|---|
|
#18+
авторЗа выделение и освобождение памяти отвечает ОС (сис вызовы или api). ОС каким-то образом хранит информацию о каждом выделенном блоке (начальный адрес и размер блока). Может в каких-нить таблицах... для любого массива в виндах верно следующее: размер в байтах iS динамического массива vM: int iS = ((long*)vM)[-4]; Кто-нить когда-нить пользовался отрицательными индексами в массивах? ;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2004, 07:44 |
|
||
|
Про память и delete
|
|||
|---|---|---|---|
|
#18+
CEMbдля любого массива в виндах верно следующее: Совсем не для любого, зависит от алгоритма работы используемого менеджера памяти. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2004, 12:46 |
|
||
|
Про память и delete
|
|||
|---|---|---|---|
|
#18+
Я пробовал в консольном VC и в Builder'е: char *c = new char[256]; int sz = ((long*)c)[-4]; ShowMessage(sz); // printf("%d",sz); delete [] c; Ни в одном случае не получил 256 :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.05.2004, 20:08 |
|
||
|
|

start [/forum/topic.php?fid=57&tid=2034965]: |
0ms |
get settings: |
6ms |
get forum list: |
10ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
52ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
32ms |
get tp. blocked users: |
1ms |
| others: | 195ms |
| total: | 312ms |

| 0 / 0 |
