Re[6]: delete и delete[ ]
От: Андрей Тарасевич Беларусь  
Дата: 30.01.07 23:24
Оценка:
Здравствуйте, Critical Error, Вы писали:

I>>Ну, например, перед первым элементом массива может храниться его размер. При попытке при помощи delete[] удалить не массив, а отдельный объект, за размер будет принято кое-что другое...


CE>Еще раз повторяю, что менаджер памяти перед любым куском памяти будь то массив или один элемент хранит размер этого массива или этого элемента. Никаких дополнительных данных нет и не нужны они. Поэтому вызов delete и delete[] для одного объекта абсолютно ничем не отличаются. Я както непонятно выражаюсь?


Понятно. Но не верно. Дополнительные данные нужны.

Да менежер памяти перед любым куском памяти хранит размер этого куска. Но это не "размер массива". И размер массива из размера куска вывести однозначно в общем случае нельзя. Если разделить размер куска на размер элемента массива, то результат получится в общем случае больше, чем размер указанный в 'new[]'. Поэтому, в случае необходимости выозва деструкторов по 'delete[]', в начале блока памяти, выделенном по 'new[]' хранятся два размера: во-первых, хранится размер сырого блока (тот самый размер, о котором ты говоришь), во-вторых, хранится еще и размер массива, указывавшийся в 'new[]' при выделении.

Вызов 'delete' и 'delete[]' для одного объекта будут совпадать только в том случае, если это объект не имеет деструктора (или имеет тривиальный деструктор). А вот если окажется что этот объект имеет нетривиальный деструктор, то вызовы 'delete' и 'delete[]' для него будут отличаться. И отличаться сильно.

Все вышесказанное является деталями "традиционной" реализации (MSVC 6, GCC). В конкретных реализациях все может быть по-другому.

См. также здесь

http://rsdn.ru/Forum/Message.aspx?mid=1693105&only=1
Автор: Андрей Тарасевич
Дата: 22.02.06
Best regards,
Андрей Тарасевич
Re[2]: delete и delete[ ]
От: Tonal- Россия www.promsoft.ru
Дата: 31.01.07 08:57
Оценка:
Здравствуйте, CompileError, Вы писали:
CE>Короче, окончательно затуманили мой мозг! Спасибо...
Кароче всё просто: если ты создал объект с помощью new, то удалять его надо с помощью delete.
А если создал массив объектов с помощью new[], то удалять его надо с помощью delete[].
Если ты сделаешь не так, никто не гарантирует как и когда упадёт твоя программа.
Что конкретно произойдёт в случае той или другой ошибки, сильно зависит от операционки, компилятора, опций оного, фазы луны и температуры за бортом.

Ну и по общим принципам кодирования/дизайна — смешивть объект и массив объектов плохой, негодный дизайн.
Re[7]: delete и delete[ ]
От: Кодт Россия  
Дата: 31.01.07 11:38
Оценка: +1
Здравствуйте, LaPerouse, Вы писали:

LP>Если я не ошибаюсь, размер массива и так хранится, при условии, что массив расположен в динамической памяти (т е в случае, если delete вообще применим).


Внутреннее устройство кучи — личное дело конкретной реализации.
Возможны варианты, когда не нужно хранить размер занятого блока рядом с блоком. Например, когда размер блока определяется прямо из адреса (есть пулы блоков разного размера).

К тому же, для менеджера кучи нужно знать именно размер блока, который кратен величине гранулярности. Например, для небольших блоков — 16 байт, а для больших — 16 кбайт.
Количество объектов, помещающихся в блок или реально в нём размещённых — это разные величины

LP>Что касается цикла по объектам, то его можно избежать, если трактовать delete именно как уничтожение массива. Как же тогда уничтожить первый элемент? Просто — явным обращением [index], т е это должна быть забота компилятора.


Да пожалуйста. Всегда выделяй память через new[] и грохай через delete[]. И только там, где тебе заведомо известно, что это один элемент, и ты хочешь сэкономить на спичках — пользуйся new/delete.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[8]: delete и delete[ ]
От: Tonal- Россия www.promsoft.ru
Дата: 31.01.07 12:29
Оценка: 28 (2)
Здравствуйте, Кодт, Вы писали:

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

LP>>Что касается цикла по объектам, то его можно избежать, если трактовать delete именно как уничтожение массива. Как же тогда уничтожить первый элемент? Просто — явным обращением [index], т е это должна быть забота компилятора.
К>Да пожалуйста. Всегда выделяй память через new[] и грохай через delete[]. И только там, где тебе заведомо известно, что это один элемент, и ты хочешь сэкономить на спичках — пользуйся new/delete.
Только один момент — при этом нужно распрощаться с удалением потомка через указатель на предка.
Ведь только delete учитывает динамический тип, а delete[] использует статический.
Этот момент как-то обошли в данном обсуждении.
Re[9]: delete и delete[ ]
От: Кодт Россия  
Дата: 31.01.07 13:32
Оценка:
Здравствуйте, Tonal-, Вы писали:

T>Только один момент — при этом нужно распрощаться с удалением потомка через указатель на предка.

T>Ведь только delete учитывает динамический тип, а delete[] использует статический.
T>Этот момент как-то обошли в данном обсуждении.

Опаньки, и действительно!
А с другой стороны, динамический массив потомков — хоть ты его new[], хоть как угодно создай — будет статически несовместим с предками. Потому что адресная арифметика уплывёт.
Следовательно, нужно или избегать таких ситуаций, или инкапсулировать. Ну а раз инкапсуляция, то можно и placement new/delete задействовать — как это делает тот же vector.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[3]: delete и delete[ ]
От: Sm0ke Россия ksi
Дата: 31.01.07 14:22
Оценка:
А если так?
typedef
  int
  some_type[10];

some_type * h= new some_type; /* вроде это преобразуется в: new int[10] */
delete h;
Re[4]: delete и delete[ ]
От: Tonal- Россия www.promsoft.ru
Дата: 01.02.07 06:14
Оценка:
Здравствуйте, Sm0ke, Вы писали:
S>А если так?
S>
S>typedef
S>  int
S>  some_type[10];
S>some_type * h= new some_type; /* вроде это преобразуется в: new int[10] */
S>delete h;
S>

И что?
Обманул сам себя — получай UB.
Можно было назвать не some_type а some_array, тогда бы удаление по delete[] выглядело бы естественно.
Или в структурку завернуть:
struct some_type {
  int arr[10];
  int& operator[](int i){return *(arr + i);}
}


Вообще, этот класс ошибок связан с тем, что указатель совмещает две разные роли, а синтаксически это никак не отражено.
Вот если бы указатель на элемент массива имел тип отличный от указателя на одиночный объект, подобных ошибок возникнуть бы не могло.
Например:
int arr[10];
int[] elt = arr + 3; //Ok
int[] elt = &arr[3]; //Ok
elt++; //ok
int*  obj = arr + 3; //err
int*  obj = static_cast<int*>(arr + 3); //Ok
int* obj = &arr[3]; //err
int* obj = static_cast<int*>(&arr[3]);
obj++ //err
Re[5]: delete и delete[ ]
От: Erop Россия  
Дата: 03.02.07 13:18
Оценка:
Здравствуйте, Left2, Вы писали:

CE>>А я говорю, что это хорошо? Я объяснил как работает delete[] и только. Выводы делайте сами, вы же программисты.

L>Ты предположил как работает delete[]. И посоветовал воспользоваться этим предположением. Я категорически против использования таких советов, о чём и написал. Ну и опять же — по твоему сообщению нельзя понять насколько серьёзно ты это предлагаешь. По нику в форуме никто не может определить уровень твоей квалификации. В итоге запросто человек неопытный может принять этот совет за чистую монету и использовать такое извращение в "боевом" коде.

Ну там же написано, что совет от критической ошибки
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: delete и delete[ ]
От: Ovl Россия  
Дата: 05.02.07 16:14
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Tonal-, Вы писали:


T>>Только один момент — при этом нужно распрощаться с удалением потомка через указатель на предка.

T>>Ведь только delete учитывает динамический тип, а delete[] использует статический.
T>>Этот момент как-то обошли в данном обсуждении.

К>Опаньки, и действительно!

К>А с другой стороны, динамический массив потомков — хоть ты его new[], хоть как угодно создай — будет статически несовместим с предками. Потому что адресная арифметика уплывёт.
К>Следовательно, нужно или избегать таких ситуаций, или инкапсулировать. Ну а раз инкапсуляция, то можно и placement new/delete задействовать — как это делает тот же vector.

стало интересно, пытался сделать тест, получилось

struct Test1 {
    Test1() { printf("Test1\r\n"); }
    virtual ~Test1() { printf("~Test1\r\n"); }

    virtual void CallMe() = 0;
};

struct Test2 : public Test1 {
    int t;

    void CallMe() {};

    Test2() { printf("Test2\r\n"); }
    virtual ~Test2() { printf("~Test2\r\n"); }
};

Test1* AllocateArray() {
    return new Test2[2];
}

void DeleteArray(Test1* arr) {
    arr[0].CallMe();
    arr[1].CallMe(); //vfpt безнадежно испорчен :(
    delete[] arr;
}

void main() {
    DeleteArray(AllocateArray());
}
Read or Die!
Как правильно задавать вопросы
Как правильно оформить свой вопрос
Автор: anvaka
Дата: 15.05.06
Re[5]: placement new/delete function-wrapper
От: Vain Россия google.ru
Дата: 05.02.07 18:33
Оценка:
Здравствуйте, Tonal-, Вы писали:

S>>А если так?

S>>
S>>typedef
S>>  int
S>>  some_type[10];
S>>some_type * h= new some_type; /* вроде это преобразуется в: new int[10] */
S>>delete h;
S>>

T>И что?
T>Обманул сам себя — получай UB.
T>Можно было назвать не some_type а some_array, тогда бы удаление по delete[] выглядело бы естественно.
T>Или в структурку завернуть:
T>
T>struct some_type {
T>  int arr[10];
T>  int& operator[](int i){return *(arr + i);}
T>}
T>


T>Вообще, этот класс ошибок связан с тем, что указатель совмещает две разные роли, а синтаксически это никак не отражено.

T>Вот если бы указатель на элемент массива имел тип отличный от указателя на одиночный объект, подобных ошибок возникнуть бы не могло.
T>Например:
T>
T>int arr[10];
T>int[] elt = arr + 3; //Ok
T>int[] elt = &arr[3]; //Ok
T>elt++; //ok
T>int*  obj = arr + 3; //err
T>int*  obj = static_cast<int*>(arr + 3); //Ok
T>int* obj = &arr[3]; //err
T>int* obj = static_cast<int*>(&arr[3]);
T>obj++ //err
T>


А вот это надёжно?
#include <stdio.h>
#include <new.h>

struct TEST {
  TEST() {
    printf(__FUNCSIG__ "\n");
  }
  ~TEST() {
    printf(__FUNCSIG__ "\n");
  }
};

template<class T> class DtorClassWrapper {
  T Wrappee;
  template<class AS> friend void DestructMeAs(void* pObj);
};

template<class AS> void ConstructMeAs(void* pObj) {
  ::new (pObj) AS;
}
template<class AS> void DestructMeAs(void* pObj) {
  //reinterpret_cast<AS*>(pObj)->AS::~AS(); //Оппа, не сработало :(
  //::delete(pObj,pObj); //И подавно, зачем тогда размещающий delete нужен? :(

  //Дубовая заплатка :)
  typedef DtorClassWrapper<AS> DTOR_TYPE;
  reinterpret_cast<DTOR_TYPE*>(pObj)->DTOR_TYPE::~DTOR_TYPE();
};

int main() {
  typedef TEST ARR[2];
  //T_ALIGNED_STORAGE<ARR,2,1> buf;
  char buf[sizeof(ARR)]; //Чхали на выравнивание..
  ConstructMeAs<ARR>(buf);
  //blabla..
  DestructMeAs<ARR>(buf);
}
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[11]: delete и delete[ ]
От: Vain Россия google.ru
Дата: 05.02.07 19:54
Оценка:
Здравствуйте, Ovl, Вы писали:

Ovl>стало интересно, пытался сделать тест, получилось

Ovl>
Ovl>struct Test1 {
Ovl>    Test1() { printf("Test1\r\n"); }
Ovl>    virtual ~Test1() { printf("~Test1\r\n"); }

Ovl>    virtual void CallMe() = 0;
Ovl>};

Ovl>struct Test2 : public Test1 {
Ovl>    int t;

Ovl>    void CallMe() {};

Ovl>    Test2() { printf("Test2\r\n"); }
Ovl>    virtual ~Test2() { printf("~Test2\r\n"); }
Ovl>};

Ovl>Test1* AllocateArray() {
Ovl>    return new Test2[2];
Ovl>}

Ovl>void DeleteArray(Test1* arr) {
Ovl>    arr[0].CallMe();
Ovl>    arr[1].CallMe(); //vfpt безнадежно испорчен :(
Ovl>    delete[] arr;
Ovl>}

Ovl>void main() {
Ovl>    DeleteArray(AllocateArray());
Ovl>}
Ovl>


Тоже пытался, но результаты честно говоря очень странные
class VOID_TYPE {};
typedef struct VTableTag* VTable;

template<class T> const VTable* GetVTablePointer() {
  static T dummy = VOID_TYPE(); //Avoiding manual-forced vfptr initializing
  return reinterpret_cast<VTable*>(*reinterpret_cast<unsigned int*>(&dummy));
}
template<class T> void SetVTablePointer(T* pObj) {
  *reinterpret_cast<const VTable**>(pObj) = GetVTablePointer<T>();
}

struct Test1 {
  Test1() { SetVTablePointer(this); } //Not needed for test, just in case
  Test1(VOID_TYPE) { } //Void constructor
  virtual ~Test1() { printf(__FUNCSIG__ "\n"); }
  virtual void CallMe() { printf(__FUNCSIG__ "\n"); }
};

struct Test2 : public Test1 {
  Test2() { SetVTablePointer(this); } //Manual-forced vfptr initializing
  Test2(VOID_TYPE) : Test1(VOID_TYPE()) { } //Void constructor
  virtual ~Test2() { printf(__FUNCSIG__ "\n"); }
  void CallMe() { printf(__FUNCSIG__ "\n"); }; //Cheking virtual function
};

Test1* AllocateArray() {
  return new Test2[2];
}

void DeleteArray(Test1* arr) {
  arr[0].CallMe();
  arr[1].CallMe(); //Works..
  delete[] arr; //Cleaning..
}

int main() {
  DeleteArray(AllocateArray());
  return 0;
}


msvc2005+sp1 (/w debugger):

void __thiscall Test2::CallMe(void)
void __thiscall Test2::CallMe(void)
__thiscall Test2::~Test2(void)
__thiscall Test1::~Test1(void)
__thiscall Test2::~Test2(void)
__thiscall Test1::~Test1(void)


msvc2005+sp1 (w/o debugger):

void __thiscall Test2::CallMe(void)
void __thiscall Test2::CallMe(void)
__thiscall Test2::~Test2(void)
__thiscall Test1::~Test1(void)
__thiscall Test2::~Test2(void)
__thiscall Test1::~Test1(void)
__thiscall Test2::~Test2(void)
__thiscall Test1::~Test1(void)
__thiscall Test1::~Test1(void)

Непонятно откуда вызвалось

comeau 4.3.3 (MODE:non-strict warnings microsoft C++)
void Test2::CallMe()
void Test2::CallMe()
Test1::~Test1()
Test1::~Test1()
Test2::~Test2()
Test1::~Test1()
Test1::~Test1()

Оригинально-симметрично..
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[6]: placement new/delete function-wrapper
От: Vain Россия google.ru
Дата: 08.02.07 03:33
Оценка:
Здравствуйте, Vain, Вы писали:

V>Здравствуйте, Tonal-, Вы писали:


S>>>А если так?

S>>>
S>>>typedef
S>>>  int
S>>>  some_type[10];
S>>>some_type * h= new some_type; /* вроде это преобразуется в: new int[10] */
S>>>delete h;
S>>>

T>>И что?
T>>Обманул сам себя — получай UB.
T>>Можно было назвать не some_type а some_array, тогда бы удаление по delete[] выглядело бы естественно.
T>>Или в структурку завернуть:
T>>
T>>struct some_type {
T>>  int arr[10];
T>>  int& operator[](int i){return *(arr + i);}
T>>}
T>>


T>>Вообще, этот класс ошибок связан с тем, что указатель совмещает две разные роли, а синтаксически это никак не отражено.

T>>Вот если бы указатель на элемент массива имел тип отличный от указателя на одиночный объект, подобных ошибок возникнуть бы не могло.
T>>Например:
T>>
T>>int arr[10];
T>>int[] elt = arr + 3; //Ok
T>>int[] elt = &arr[3]; //Ok
T>>elt++; //ok
T>>int*  obj = arr + 3; //err
T>>int*  obj = static_cast<int*>(arr + 3); //Ok
T>>int* obj = &arr[3]; //err
T>>int* obj = static_cast<int*>(&arr[3]);
T>>obj++ //err
T>>


V>А вот это надёжно?

V>
V>#include <stdio.h>
V>#include <new.h>

V>struct TEST {
V>  TEST() {
V>    printf(__FUNCSIG__ "\n");
V>  }
V>  ~TEST() {
V>    printf(__FUNCSIG__ "\n");
V>  }
V>};

V>template<class T> class DtorClassWrapper {
V>  T Wrappee;
V>  template<class AS> friend void DestructMeAs(void* pObj);
V>};

V>template<class AS> void ConstructMeAs(void* pObj) {
V>  ::new (pObj) AS;
V>}
V>template<class AS> void DestructMeAs(void* pObj) {
V>  //reinterpret_cast<AS*>(pObj)->AS::~AS(); //Оппа, не сработало :(
V>  //::delete(pObj,pObj); //И подавно, зачем тогда размещающий delete нужен? :(

V>  //Дубовая заплатка :)
V>  typedef DtorClassWrapper<AS> DTOR_TYPE;
V>  reinterpret_cast<DTOR_TYPE*>(pObj)->DTOR_TYPE::~DTOR_TYPE();
V>};

V>int main() {
V>  typedef TEST ARR[2];
V>  //T_ALIGNED_STORAGE<ARR,2,1> buf;
V>  char buf[sizeof(ARR)]; //Чхали на выравнивание..
V>  ConstructMeAs<ARR>(buf);
V>  //blabla..
V>  DestructMeAs<ARR>(buf);
V>}
V>

up
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[12]: delete и delete[ ]
От: Vain Россия google.ru
Дата: 08.02.07 03:34
Оценка:
Здравствуйте, Vain, Вы писали:

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


Ovl>>стало интересно, пытался сделать тест, получилось

Ovl>>
Ovl>>struct Test1 {
Ovl>>    Test1() { printf("Test1\r\n"); }
Ovl>>    virtual ~Test1() { printf("~Test1\r\n"); }

Ovl>>    virtual void CallMe() = 0;
Ovl>>};

Ovl>>struct Test2 : public Test1 {
Ovl>>    int t;

Ovl>>    void CallMe() {};

Ovl>>    Test2() { printf("Test2\r\n"); }
Ovl>>    virtual ~Test2() { printf("~Test2\r\n"); }
Ovl>>};

Ovl>>Test1* AllocateArray() {
Ovl>>    return new Test2[2];
Ovl>>}

Ovl>>void DeleteArray(Test1* arr) {
Ovl>>    arr[0].CallMe();
Ovl>>    arr[1].CallMe(); //vfpt безнадежно испорчен :(
Ovl>>    delete[] arr;
Ovl>>}

Ovl>>void main() {
Ovl>>    DeleteArray(AllocateArray());
Ovl>>}
Ovl>>


V>Тоже пытался, но результаты честно говоря очень странные

V>
V>class VOID_TYPE {};
V>typedef struct VTableTag* VTable;

V>template<class T> const VTable* GetVTablePointer() {
V>  static T dummy = VOID_TYPE(); //Avoiding manual-forced vfptr initializing
V>  return reinterpret_cast<VTable*>(*reinterpret_cast<unsigned int*>(&dummy));
V>}
V>template<class T> void SetVTablePointer(T* pObj) {
V>  *reinterpret_cast<const VTable**>(pObj) = GetVTablePointer<T>();
V>}

V>struct Test1 {
V>  Test1() { SetVTablePointer(this); } //Not needed for test, just in case
V>  Test1(VOID_TYPE) { } //Void constructor
V>  virtual ~Test1() { printf(__FUNCSIG__ "\n"); }
V>  virtual void CallMe() { printf(__FUNCSIG__ "\n"); }
V>};

V>struct Test2 : public Test1 {
V>  Test2() { SetVTablePointer(this); } //Manual-forced vfptr initializing
V>  Test2(VOID_TYPE) : Test1(VOID_TYPE()) { } //Void constructor
V>  virtual ~Test2() { printf(__FUNCSIG__ "\n"); }
V>  void CallMe() { printf(__FUNCSIG__ "\n"); }; //Cheking virtual function
V>};

V>Test1* AllocateArray() {
V>  return new Test2[2];
V>}

V>void DeleteArray(Test1* arr) {
V>  arr[0].CallMe();
V>  arr[1].CallMe(); //Works..
V>  delete[] arr; //Cleaning..
V>}

V>int main() {
V>  DeleteArray(AllocateArray());
V>  return 0;
V>}
V>


V>msvc2005+sp1 (/w debugger):

V>

V>void __thiscall Test2::CallMe(void)
V>void __thiscall Test2::CallMe(void)
V>__thiscall Test2::~Test2(void)
V>__thiscall Test1::~Test1(void)
V>__thiscall Test2::~Test2(void)
V>__thiscall Test1::~Test1(void)


V>msvc2005+sp1 (w/o debugger):

V>

V>void __thiscall Test2::CallMe(void)
V>void __thiscall Test2::CallMe(void)
V>__thiscall Test2::~Test2(void)
V>__thiscall Test1::~Test1(void)
V>__thiscall Test2::~Test2(void)
V>__thiscall Test1::~Test1(void)
V>__thiscall Test2::~Test2(void)
V>__thiscall Test1::~Test1(void)
V>__thiscall Test1::~Test1(void)

V>Непонятно откуда вызвалось

V>comeau 4.3.3 (MODE:non-strict warnings microsoft C++)

V>
V>void Test2::CallMe()
V>void Test2::CallMe()
V>Test1::~Test1()
V>Test1::~Test1()
V>Test2::~Test2()
V>Test1::~Test1()
V>Test1::~Test1()
V>

V>Оригинально-симметрично..
up
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[5]: delete и delete[ ]
От: Programador  
Дата: 07.03.07 16:30
Оценка: -1
Здравствуйте, Tonal-, Вы писали:

T>Вообще, этот класс ошибок связан с тем, что указатель совмещает две разные роли, а синтаксически это никак не отражено.

T>Вот если бы указатель на элемент массива имел тип отличный от указателя на одиночный объект, подобных ошибок возникнуть бы не могло.

По значанию различимы
    y=new A[1];
    x=new A();
    y=new A[1];
    x=new A();
    y=new A[1];
    x=new A();
    x=new A();
    x=new A();
    x=new A();
    y=new A[1];
    y=new A[1];
    y=new A[1];
    y=new A[1];

в отладчике оверхеад видно. посдедняя цифра в [] не 0.

Здравствуйте, Кодт, Вы писали:

К>Да пожалуйста. Всегда выделяй память через new[] и грохай через delete[]. И только там, где тебе заведомо известно, что это один элемент, и ты хочешь сэкономить на спичках — пользуйся new/delete.


есть еще new A() и new A(орлор,олдол,йцуцй)

так что для автоматического удаления по выходу из контекста (тоесть ретурн далеко, а то и не один) велосипед нужен или 2 отдельных.

template <class T >struct autoVelo
{ T* privatPtr;
  inline autoVelo(T*p){privatPtr=p;}
  inline operator T*(){return privatPtr;} 
  inline ~autoVelo()
   { if(privatPtr)
     if(0xF&(unsigned)(void*)privatPtr)
       delete[] privatPtr;
     else
        delete privatPtr;     
   }
  private:
  operator =( autoVelo<T>){}
};


..............
    autoVelo<A> a0(new A [1] );
    autoVelo<A> a1(new A (9,9) );

А все смарт посему не катят хош буст хош не буст
Re[6]: delete и delete[ ]
От: Programador  
Дата: 07.03.07 17:00
Оценка:
только проверить нужно наверно там 7 а не F
Re[7]: delete и delete[ ]
От: Programador  
Дата: 07.03.07 17:33
Оценка:
пожалуй inline operator T*() нужно убрать и пользовать так

A *b=x?&new A():new Abc(..)
MAKRO(A,b)
// autoVelo<A> const MOZGI_NE_POMNIT##b(b);
Re[6]: delete и delete[ ]
От: Zigmar Израиль  
Дата: 07.03.07 19:34
Оценка:
Здравствуйте, Programador, Вы писали:
P>
P>     if(0xF&(unsigned)(void*)privatPtr)
P>


Это что за бред такой?! Ты полагаешься на какие-то особенности выделения памяти на каком-то конкретном компиляторе и платформе. Более того, я думаю что это даже на том-же компиляторе не завалится, если чуть чуть поменять настройки или например, тип будет с какой-нибудь виртуальным наследованием или еще какой особенностью. И это не называется "велосипед" — это, скорее можно отнести к разряду опасных багов.

P>А все смарт посему не катят

Смарт или не смарт — это не важно. Если выделял массив — удаляй как массив. Если как один объект — удаляй соответственно. Точка. Третьего не дано. А если в коде не знаешь как был выделен указатель — выбрось такой код на помойку, или перепиши нафиг.
"To protect people you must slay people. To let people live you must let people die. This is the true teaching of the sword."
-Seijuro Hiko, "Rurouni Kensin"
Re[7]: delete и delete[ ]
От: Programador  
Дата: 08.03.07 13:07
Оценка:
Здравствуйте, Zigmar, Вы писали:

А разве я обещал что-то гарантировать я даже в релизе эту вещь не проверял. И вообще не понитаю зачем в 32 нужна грануляция больше 4. Но здесь по дизайну нужно 2 константных, без оператора= один типа режеренс, для симуляции автоматической (автоматической в семантике С++) переменной, второй для симуляции автоматического массива.
Re[2]: delete и delete[ ]
От: Аноним  
Дата: 08.03.07 14:11
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>На самом деле, весьма вероятно, что произойдет разрушения кучи. Не вызов деструкторов по сравнению с этим -- мелкое хулиганство.


Не "мелкое хулиганство", а утечка памяти. При работе в цикле это очень быстро способно вычерпать всю память и поставить машину на колени.
Например, недавно поступила жалоба, что некоторая софтина сжирает гиг памяти. Выяснилось, что причина — утечки памяти. Небольшие, но регулярные.
Re[8]: delete и delete[ ]
От: Аноним  
Дата: 08.03.07 14:21
Оценка:
Здравствуйте, MikelSV, Вы писали:

MSV>Может не совсем правильное, но быстрое решение задачи


Мой дорогой друг, желаю Вам скорейшего попадания в большую команду, где любое скорейшее но не совсем правильное решение будет вылезать на глаза. Тогда оптимизма у Вас поубавится. А сейчас Вы просто живете за счет Вашего последователя, бездумно сваливая на его голову ворох Ваших нерешенных проблем.

И уж он Вас вспомнит не раз и не два, делом и словом. Коротким, но не совсем добрым
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.