Re[3]: new / delete
От: Alex_Avr Россия  
Дата: 13.03.06 11:52
Оценка: 3 (1)
Здравствуйте, vitaly1979, Вы писали:


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


NB>>
NB>>for (int j=0; j<10; ++j) delete st[j];
NB>>


V>хм, интересно

V>почему не delete [] ?

Потому что удаляется отдельный объект, а не массив объектов.
Вообще, операторы new[] / delete[] используются для создания / удаления массивов объектов;
операторы new и delete используются для создания / удаления отдельных объектов.

V>и в какой то программе, в примерах по программированию, я видел тоже массив указателей на массивы типа char,

V>и все это удалялось так:

V>
V>char** parr=NULL;
V>parr = new char* [10];
V>for(n=0;n<10;n++)
V>{
V>   parr[n] = new char [100];
V>}

V>delete parr;
V>


V>удалится ли вся память таким образом?


В этом примере создается массив указателей типа char*, состоящий из 10 элементов.
На каждой итерации цикла создается массив из 100 элементов типа char, и адрес первого (с индексом 0) элемента в массиве присваивается
элементу массива parr.

Здесь с удалением две проблемы:
1) Не удаляется память, которая выделялась в цикле — утечка памяти в 10 массивов * 100 элементов = 1000 элементов типа char.
2) Для освобождения памяти, на которую указывает указатель par, используется неправильный оператор — delete, а не delete[],
как должно быть. То есть память, выделенная под массив, освобождается как память, выделенная под один
элемент массива — одиночный объект. Это является неопределенным поведением (undefined behaviour, UB), т.е.
в данном случае может произойти повреждение памяти со всеми вытекающими последствиями.

Правильно было бы так:

char** parr = NULL;
parr = new char* [10];
size_t n;

for(n = 0; n < 10; n++)
{
   parr[n] = new char [100];
}

// Освобождение выделенной памяти
for(n = 0; n < 10; ++n)
{
   delete[] parr [n];
}

delete[] parr;


Чтобы упростить себе жизнь, лучше использовать стандартный контейнер из STL std::vector.
С его использованием твой первоначальный пример будет выглядеть так:

#include <vector>

struct CStruct {
 int i;
 CString Caption;
};

int main ()
{
  std::vector<CStruct> st (10);

  size_t count = st.size ();
  for (size_t i = 0; i < count; ++i)
  {
    st[i].i = 2;
    st[i].Caption = "22";
  }
  return 0;
}


В данном случае после завершения функции main вся выделенная память автоматически будет освобождена деструкторм класса std::vector.
С уважением, Александр Авраменко.
Re[5]: new / delete
От: BitField Украина http://lazy-bitfield.blogspot.com
Дата: 13.03.06 13:55
Оценка: +1
Здравствуйте, programmater, Вы писали:

P>без всяких там глупых [], и никогда никаких проблем или утечек памяти отродясь не было? Я что, получается написал гору бесполезного кода?


Ну, не бесполезного. А с УБ. А частный случай УБ -- правильно работающая программа.. Советую переписать от греха подальше -- сменишь компилятор, а то и платформу -- и будешь потом неделю багу искать...
Re[5]: new / delete
От: Left2 Украина  
Дата: 13.03.06 13:58
Оценка: +1
P>Интересно, а почему я всю жысь выделяю память используя

Да потому что везло. Потому что operator new[]() и operator new() в MS Visual Studio традиционно возвращают совместимые результаты. Попробуй чуть более другой компилятор — и тебя будут ждать неприятные сюрпризы...

И вообще — вызов delete[] ручками — это прошлый век, используй std::vector как завещал Саттер
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
new / delete
От: Аноним  
Дата: 13.03.06 07:38
Оценка:
Извиняюсь за такой глупый вопрос. Есть структура, есть массив указателей на структуру. Я заполняю массив в начале программы.
struct CStruct {
 int i;
 CString Caption;
};
CStruct* st[10];
for (int j = 0; j < 10; j++) 
{
 CStruct* s1 = new CStruct*;
 s1->i = 2;
 s1->Caprtion = "22";
 st[j] = s1;
}

Как мне при выходе из программы освободить память? Я вроде понимаю, что мне надо пройти по всему массиву и освободить. Но как именно не понимаю.
Re: new / delete
От: night beast СССР  
Дата: 13.03.06 07:42
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Извиняюсь за такой глупый вопрос. Есть структура, есть массив указателей на структуру. Я заполняю массив в начале программы.

А>
А>struct CStruct {
А> int i;
А> CString Caption;
А>};
А>CStruct* st[10];
А>for (int j = 0; j < 10; j++) 
А>{
А> CStruct* s1 = new CStruct*;

замени на
CStruct* s1 = new CStruct;

А> s1->i = 2;
А> s1->Caprtion = "22";
А> st[j] = s1;
А>}
А>

А>Как мне при выходе из программы освободить память? Я вроде понимаю, что мне надо пройти по всему массиву и освободить. Но как именно не понимаю.


for (int j=0; j<10; ++j) delete st[j];
Re: new / delete
От: srggal Украина  
Дата: 13.03.06 07:44
Оценка:
Здравствуйте, <Аноним>, Вы писали:


Откажитесь от явного использования массива и выделяйте сразу необходимое кол-во через s1 = new CStruct[10] с последующим delete[] s1
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: new / delete
От: axexa  
Дата: 13.03.06 07:44
Оценка:
for (int j = 0; j < 10; j++)
{
  CStruct* s1 = st[j];
  delete s1;
}


Re[2]: new / delete
От: srggal Украина  
Дата: 13.03.06 07:46
Оценка:
Здравствуйте, srggal, Вы писали:

Добавлю, что-то как-то странно выглядит этв строчка:
 CStruct* s1 = new CStruct*;


Выделенное не нужно, видимо из-за этой ошибки Вы и запутались
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: new / delete
От: vitaly1979  
Дата: 13.03.06 10:49
Оценка:
Здравствуйте, night beast, Вы писали:

NB>
NB>for (int j=0; j<10; ++j) delete st[j];
NB>



хм, интересно
почему не delete [] ?
и в какой то программе, в примерах по программированию, я видел тоже массив указателей на массивы типа char,
и все это удалялось так:

char** parr=NULL;
parr = new char* [10];
for(n=0;n<10;n++)
{
   parr[n] = new char [100];
}

delete parr;


удалится ли вся память таким образом?
Re[3]: new / delete
От: night beast СССР  
Дата: 13.03.06 10:55
Оценка:
Здравствуйте, vitaly1979, Вы писали:


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


NB>>
NB>>for (int j=0; j<10; ++j) delete st[j];
NB>>



V>хм, интересно

V>почему не delete [] ?

а потому что он new [] не вызавал.

V>и в какой то программе, в примерах по программированию, я видел тоже массив указателей на массивы типа char,

V>и все это удалялось так:

V>
V>char** parr=NULL;
V>parr = new char* [10];
V>for(n=0;n<10;n++)
V>{
V>   parr[n] = new char [100];
V>}

V>delete parr;
V>


V>удалится ли вся память таким образом?


нет. не удалится. надо

for(n=0;n<10;n++) { delete [] parr[n]; }
delete [] parr;

принцып простой — каждому new (new[]) свой delete (delete []).
Re[4]: new / delete
От: programmater  
Дата: 13.03.06 13:05
Оценка:
Здравствуйте, night beast, Вы писали:

NB>нет. не удалится. надо


NB>for(n=0;n<10;n++) { delete [] parr[n]; }

NB>delete [] parr;

NB>принцып простой — каждому new (new[]) свой delete (delete []).


Интересно, а почему я всю жысь выделяю память используя

char* MyPtr = new char[n]; // (char - это к примеру, может быть int, short, double...)

а удаляю всегда

delete MyPtr;


без всяких там глупых [], и никогда никаких проблем или утечек памяти отродясь не было? Я что, получается написал гору бесполезного кода?
Re[5]: new / delete
От: night beast СССР  
Дата: 13.03.06 13:10
Оценка:
Здравствуйте, programmater, Вы писали:

P>Здравствуйте, night beast, Вы писали:


NB>>нет. не удалится. надо


NB>>for(n=0;n<10;n++) { delete [] parr[n]; }

NB>>delete [] parr;

NB>>принцып простой — каждому new (new[]) свой delete (delete []).


P>Интересно, а почему я всю жысь выделяю память используя


P>
P>char* MyPtr = new char[n]; // (char - это к примеру, может быть int, short, double...)
P>

P> а удаляю всегда

P>
P>delete MyPtr;
P>


не те книжки читал?

P>без всяких там глупых [], и никогда никаких проблем или утечек памяти отродясь не было? Я что, получается написал гору бесполезного кода?


ну, если есть бинарники, и они приносят пользу, то не бесполезного...
Re[4]: new / delete
От: vitaly1979  
Дата: 13.03.06 14:24
Оценка:
Здравствуйте, Alex_Avr, Вы писали:

.....

спасибо за подробный ответ
Re[5]: new / delete
От: Alex_Avr Россия  
Дата: 14.03.06 10:16
Оценка:
Здравствуйте, vitaly1979, Вы писали:

V>спасибо за подробный ответ


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