Operator delete[]
От: Owen Украина  
Дата: 19.09.07 07:29
Оценка:
Привет Олл!

Сори за тупой вопрос. Как он опредиляет длину удаляемого участка памяти?

Спасибо.
Re: Operator delete[]
От: Erop Россия  
Дата: 19.09.07 07:50
Оценка:
Здравствуйте, Owen, Вы писали:

O>Привет Олл!


O>Сори за тупой вопрос. Как он опредиляет длину удаляемого участка памяти?


Обычно она, как истина, записано "где-то рядом"
Но в целом это не обязательно. "Они знают" вот точный ответ

p. s.
На досуге советую подумать как работают Cишные функции alloc и free
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Operator delete[]
От: dip_2000 Россия  
Дата: 19.09.07 07:51
Оценка:
Здравствуйте, Owen, Вы писали:

O>Привет Олл!

И Вам не болеть!

O>Сори за тупой вопрос. Как он опредиляет длину удаляемого участка памяти?

Чаще всего оператор new перед выделяемым блоком памяти записывает служебную информацию Это и есть длинна. Только полагаться на это не стоит, а использовать — тем более

O>Спасибо.

Re: Operator delete[]
От: alzt  
Дата: 19.09.07 07:55
Оценка:
Здравствуйте, Owen, Вы писали:

O>Привет Олл!


O>Сори за тупой вопрос. Как он опредиляет длину удаляемого участка памяти?


O>Спасибо.


Например оператор new[] может записывать её размер перед выделенным участком памяти. Зависит от реализации, поэтому использование delete вместо delete[] в общем случае не безопасно.
Re[2]: Operator delete[]
От: Owen Украина  
Дата: 19.09.07 08:15
Оценка:
Здравствуйте, dip_2000,

Спасибо.
Re[2]: Operator delete[]
От: Owen Украина  
Дата: 19.09.07 08:21
Оценка:
Здравствуйте, alzt, Вы писали:

A>Здравствуйте, Owen, Вы писали:


O>>Привет Олл!


O>>Сори за тупой вопрос. Как он опредиляет длину удаляемого участка памяти?


O>>Спасибо.


A>Например оператор new[] может записывать её размер перед выделенным участком памяти. Зависит от реализации, поэтому использование delete вместо delete[] в общем случае не безопасно.

Я только что экспериментировал и почему-то delete удаляет нормально после new[]. Или это чистое везение?
Re[3]: Operator delete[]
От: Erop Россия  
Дата: 19.09.07 08:45
Оценка:
Здравствуйте, Owen, Вы писали:

O>Я только что экспериментировал и почему-то delete удаляет нормально после new[]. Или это чистое везение?


Попробуй воспользоваться поиском по тут, например

Ещё можешь попробовать поудалять вектор объектов с деструктором, скажем std::string'ов...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Operator delete[]
От: CreatorCray  
Дата: 19.09.07 08:54
Оценка: :)
Здравствуйте, Owen, Вы писали:

A>>Например оператор new[] может записывать её размер перед выделенным участком памяти. Зависит от реализации, поэтому использование delete вместо delete[] в общем случае не безопасно.

O>Я только что экспериментировал и почему-то delete удаляет нормально после new[]. Или это чистое везение?
В общем случае разница между delete и delete [] в том, что удалении массива элементов при помощи delete будет вызван деструктор только для первого элемента. Соответственно для POD типов это безопасно, но при удалении массива классов будут побочные эффекты. Впрочем могут быть еще какие нибудь нюансы в замороченных компиляторах.
Так что выделенное при помощи new [] киляй через delete [] всегда, и будет тебе "щасте".
А после того, как отработали деструкторы для указателя в обоих случаях зовется free.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[3]: Operator delete[]
От: Sharp Eye Россия  
Дата: 19.09.07 08:56
Оценка:
Здравствуйте, Owen, Вы писали:

O>Здравствуйте, alzt, Вы писали:


A>>Здравствуйте, Owen, Вы писали:


O>>>Привет Олл!


O>>>Сори за тупой вопрос. Как он опредиляет длину удаляемого участка памяти?


O>>>Спасибо.


A>>Например оператор new[] может записывать её размер перед выделенным участком памяти. Зависит от реализации, поэтому использование delete вместо delete[] в общем случае не безопасно.

O>Я только что экспериментировал и почему-то delete удаляет нормально после new[]. Или это чистое везение?

Попробуй:



class Foo
{
public:
    Foo()
    {
        std::cout << "Foo()" << std::endl;
    }

    ~Foo()
    {
        std::cout << "~Foo()" << std::endl;
    }
};

int main()
{
    Foo * arr = new Foo[2];

    delete arr; // delete [] arr;

    return 0;
}

Вываливаетцо.
Re[4]: Operator delete[]
От: dip_2000 Россия  
Дата: 19.09.07 09:03
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Здравствуйте, Owen, Вы писали:


A>>>Например оператор new[] может записывать её размер перед выделенным участком памяти. Зависит от реализации, поэтому использование delete вместо delete[] в общем случае не безопасно.

O>>Я только что экспериментировал и почему-то delete удаляет нормально после new[]. Или это чистое везение?
CC>В общем случае разница между delete и delete [] в том, что удалении массива элементов при помощи delete будет вызван деструктор только для первого элемента. Соответственно для POD типов это безопасно
По стандарту это UB. Точка.
Все остальное — везение.
Например при удалении массива char ов(куда уж боелее POD тип!) на WM 5.0 при помощи delete — портиться куча, и спустя несколько таких циклов new []/ delete при попытке сделать new(совсем в другом месте заметте) все падает.
(есстесственно эксперемент проводился непреднамерено )
Re[5]: Operator delete[]
От: CreatorCray  
Дата: 19.09.07 09:25
Оценка:
Здравствуйте, dip_2000, Вы писали:

CC>>В общем случае разница между delete и delete [] в том, что удалении массива элементов при помощи delete будет вызван деструктор только для первого элемента. Соответственно для POD типов это безопасно

_>По стандарту это UB. Точка.
_>Например при удалении массива char ов(куда уж боелее POD тип!) на WM 5.0 при помощи delete — портиться куча, и спустя несколько таких циклов new []/ delete при попытке сделать new(совсем в другом месте заметте) все падает.
Само собой. Потому что implemetation specific. Мне этот термин нравится больше чем UB.
Падает потому, что указатель, который ты получаешь из new, свинут вперед относительно реального начала выделенной области для того, чтоб разместить там кол-во созданных объектов. Потому у тя освобождение памяти и того... По неверному указателю.
Есть рантаймы в который подобные фокусы прокатывают и все нормально удаляется. Один раз даже попался код, который эту фичу использовал. Пока вкурил как он работает думал свихнусь. Нафиг такие ништяки.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re: Operator delete[]
От: Awaken Украина  
Дата: 19.09.07 09:28
Оценка:
O>Сори за тупой вопрос. Как он опредиляет длину удаляемого участка памяти?

по дескриптору занятого блока.
как именно организованы эти дескрипторы, зависит от реализации,
но скорее всего он находится с минусовым смещением от адреса занимаемого объектом
Re: Operator delete[]
От: Vamp Россия  
Дата: 19.09.07 09:48
Оценка:
O>Сори за тупой вопрос. Как он опредиляет длину удаляемого участка памяти?

Да собственно, точно так же как и обычный delete. Тебя же не удивляет, что в такой ситуации

struct A  {
   int size[1024];
}; 

struct B : A  {
   int size[1024 * 5];
}; 

int main() {
   A* a = new B;
   delete a;


удаляется объект размером с B?
Да здравствует мыло душистое и веревка пушистая.
Re[4]: Operator delete[]
От: Owen Украина  
Дата: 19.09.07 11:49
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Так что выделенное при помощи new [] киляй через delete [] всегда, и будет тебе "щасте".

CC>А после того, как отработали деструкторы для указателя в обоих случаях зовется free.

а почему бы все не удалять оператором delete []?
Re[2]: Operator delete[]
От: Owen Украина  
Дата: 19.09.07 11:53
Оценка: -1 :)
Здравствуйте, Awaken, Вы писали:

O>>Сори за тупой вопрос. Как он опредиляет длину удаляемого участка памяти?


A>по дескриптору занятого блока.

A>как именно организованы эти дескрипторы, зависит от реализации,
A>но скорее всего он находится с минусовым смещением от адреса занимаемого объектом

У ты дал. Деструктор находится там где любая функция... Если виртуальный то его адрес в таблице виртуальных функций, если нет, то его компилятор знает где искать.
Я имел в виду длину вектора удаляемого, а не размер самого обьекта
Re[2]: Operator delete[]
От: Owen Украина  
Дата: 19.09.07 11:55
Оценка:
Здравствуйте, Vamp, Вы писали:


O>>Сори за тупой вопрос. Как он опредиляет длину удаляемого участка памяти?


V>Да собственно, точно так же как и обычный delete. Тебя же не удивляет, что в такой ситуации


V>
V>struct A  {
V>   int size[1024];
V>}; 

V>struct B : A  {
V>   int size[1024 * 5];
V>}; 

V>int main() {
V>   A* a = new B;
V>   delete a;
V>


V>удаляется объект размером с B?


Так здесь понятно, что по деструктору определяет, а вот массив не имеет деструктора...
Re[5]: Operator delete[]
От: CreatorCray  
Дата: 19.09.07 12:19
Оценка:
Здравствуйте, Owen, Вы писали:

O>Здравствуйте, CreatorCray, Вы писали:


CC>>Так что выделенное при помощи new [] киляй через delete [] всегда, и будет тебе "щасте".

CC>>А после того, как отработали деструкторы для указателя в обоих случаях зовется free.

O>а почему бы все не удалять оператором delete []?

Хотя бы потому, что в большинстве реализаций delete [] полезет туда, где должно хранится кол-во объектов, которое было выделено new [] и естественно его там не найдет. Вернее найдет какое то число, и попытается исходя из полученного значения вызвать деструкторы у этого кол-ва объектов... Что приведет к громкому БУМ. А для POD типов оно может попытаться освободить память по адресу ptr-4, что тоже ни к чему хорошему не приведет. Прокатит это только на некотором колве реализаций.

Так что лучше пиши по стандарту : new -> delete, new [] -> delete []
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[3]: Operator delete[]
От: CreatorCray  
Дата: 19.09.07 12:19
Оценка:
Здравствуйте, Owen, Вы писали:

O> У ты дал. Деструктор находится там где любая функция... Если виртуальный то его адрес в таблице виртуальных функций, если нет, то его компилятор знает где искать.

O>Я имел в виду длину вектора удаляемого, а не размер самого обьекта

В VC7.1 new [] и delete[] работает примерно так:
псевдокоТ
TYPE* new TYPE [number]
{
    void *ptr = malloc (number*sizeof(TYPE)+sizeof(int));
    int* iPtr = (int*)ptr;
    *iPtr = number;
    TYPE* tPtr = (TYPE*)(iPtr+1);
    
    for (int i=0;i<number;i++)
        вызов конструктора для tPtr[i];
        
    return tPtr;
}

void delete [] (TYPE *ptr)
{
    int *iPtr = (int*)ptr;
    int number = *(--iPtr);
    TYPE *tPtr = (TYPE*)ptr;
    
    for (int i=0;i<number;i++)
        вызов деструктора для tPtr[i];
    
    free (iPtr);
}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[2]: Operator delete[]
От: Roman Odaisky Украина  
Дата: 19.09.07 12:59
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Да собственно, точно так же как и обычный delete. Тебя же не удивляет, что в такой ситуации


V>
V>struct A  {
V>   int size[1024];
V>}; 

V>struct B : A  {
V>   int size[1024 * 5];
V>}; 

V>int main() {
V>   A* a = new B;
V>   delete a;
V>


V>удаляется объект размером с B?


Удивляет: должен винчестер форматироваться ;-)

Это тоже UB: удаление объекта по указателю на базовый класс, не имеющий виртуального деструктора.
До последнего не верил в пирамиду Лебедева.
Re[3]: Operator delete[]
От: Vamp Россия  
Дата: 19.09.07 13:04
Оценка:
RO>Удивляет: должен винчестер форматироваться

А объект удаляется, тем не менее.
Да здравствует мыло душистое и веревка пушистая.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.