Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Memory leaks, С и С++ при работе с памятью 
:(
    Опции темы
brb
  Дата 11.1.2003, 00:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 190
Регистрация: 7.1.2003

Репутация: нет
Всего: нет



Я старый(и по возрасту тоже  :huh ) и закоренелий Сишник. С памятью работал много и безпроблемно. На билдере реализовал такой код:
  PayState    *ptr;   // класс поинтер вестимо
  PayState    *pPayState[1200];
 
  for (i = 0; pPayState[i] != NULL; i++ )delete pPayState[i];
  // я думал, что тут я освобождаю всю занятую память
  i = 0;
  do {
     ptr = new PayState ( bc, ic ); // конструктор - аллокирует новую запись
     if ( ptr != NULL ){            // успешно
        bc = ptr->Balance();        // какой-то дурацкий код...
        ic = ptr->Bank();
        pPayState[i++] = ptr;       //Поместить в массив для дальнейших нужд  
     }
     else {
        ShowMessage ("Not enough memory, Sorry");
        exit ( EXIT_FAILURE );
     }
  } while ( bc );                   // больше записей нет!

Хоть и С++, но все так, как и должно быть в С. Итог - не работает
Тот же пример но в С++ (говорю честно, срисовал без понимания)

  delete[] pPayState;               //  ЧТО ЖЕ ЭТО ЗА ТАКОЕ???????
  i = 0;
  do {
     ptr = new PayState ( bc, ic );
     if ( ptr != NULL ){
        bc = ptr->Balance();
        ic = ptr->Bank();
        pPayState[i++] = ptr;
     }
     else {
        ShowMessage ("Not enough memory, Sorry");
        exit ( EXIT_FAILURE );
     }
  } while ( bc );

Так - нет проблем! Люди грамотные, объясните в чем дело? Я и синтаксиса такого не знаю: delete[] pPayState;

Заранее благодарен
--------------------
Сказки - удивительная вещь! Самое удивительное, что в них верят только маленькие дети, которым их рассказывают мамы и мамы, которым их рассказывают подросшие дети.
PM MAIL   Вверх
Baa
Дата 11.1.2003, 01:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2639
Регистрация: 12.4.2002
Где: Москва

Репутация: 8
Всего: 12



>Я и синтаксиса такого не знаю: delete[] pPayState;
char* lpBuffer = new char [0xFF];
delete [] lpBuffer;
delete [] lpBuffer освобождает ВСЮ память, выделенную нами ранее под МАССИВ символов.




--------------------
"Duty is everything; the greatest of joys, the deepest of sorrows" Aribeth de Tylmarande
PM ICQ   Вверх
brb
Дата 11.1.2003, 04:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 190
Регистрация: 7.1.2003

Репутация: нет
Всего: нет



>char* lpBuffer = new char [0xFF];
>delete [] lpBuffer;
>delete [] lpBuffer освобождает ВСЮ память, выделенную нами ранее под МАССИВ >символов.
А в чем же разница между
delete [] lpBuffer;
и
delete lpBuffer;
И то и другое освобождоют выделенный фрагмент памяти или надо как в Си
free lpBuffer;
a delete lpBuffer;
не проходит?
--------------------
Сказки - удивительная вещь! Самое удивительное, что в них верят только маленькие дети, которым их рассказывают мамы и мамы, которым их рассказывают подросшие дети.
PM MAIL   Вверх
skaa
Дата 11.1.2003, 06:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 24.12.2002
Где: Skokie, IL

Репутация: нет
Всего: нет



delete [] lpBuffer удаляет все элементы массива lpBuffer, а delete lpBuffer освобождает распределённую память, указатель на которую lpBuffer.
PM MAIL WWW   Вверх
brb
Дата 11.1.2003, 09:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 190
Регистрация: 7.1.2003

Репутация: нет
Всего: нет



skaa, замечательное наблюдение!
А как освободить незанятую память? Освободить от чего?
Уважаемый, верните мне, пожалуйста, должок, который Вы у меня не брали! :thumbs-up
--------------------
Сказки - удивительная вещь! Самое удивительное, что в них верят только маленькие дети, которым их рассказывают мамы и мамы, которым их рассказывают подросшие дети.
PM MAIL   Вверх
Vaulter
Дата 11.1.2003, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1724
Регистрация: 30.12.2002
Где: бункер

Репутация: 2
Всего: 22



что у тебя в деструкторе PayState?


--------------------
PM MAIL WWW ICQ   Вверх
brb
Дата 12.1.2003, 03:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 190
Регистрация: 7.1.2003

Репутация: нет
Всего: нет



Что Бог то бишь Борланд послал. А мысль в чем?
--------------------
Сказки - удивительная вещь! Самое удивительное, что в них верят только маленькие дети, которым их рассказывают мамы и мамы, которым их рассказывают подросшие дети.
PM MAIL   Вверх
Fantasist
Дата 12.1.2003, 03:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Не, какая-то ерунда. Надо бы узнать, что значит "не работает". Вот у тебя объявление:

PayState    *pPayState[1200];

Это есть 1200 указателей на PayState, причем выделенных на стеке (или в сегменте данных, если она глобальная, но это детали). Применять к этой переменной delete[] ни в коем случае нельзя, и в цикле освобождать - правильное решение.
delete применяется к указателям, память для которых была выделенна с помощью new, а delete[] применяется к указателям, память для которых была выделенна с помощью new[]. На первых порах этого достадочно. В принципе, на тему нужно ли delete[] и не достадочно ли просто delete, было много обсуждений, но по стандарту пока остается так. В основном разница в том, что выделяя память через new для классов, не нужно хранить количество выделенных элементов, чтобы знать сколько раз вызывать конструктор, и в delete не нужно их считывать. То есть, если оставить только delete, то это количество надо будет хранить всегда.
 
 Должен зказать, что в данном случае, по видимому, лучше использовать стандартные классы библиотеки С++, такие как std::vector, std::deque. В них можно запихивать объекты, и доставать их, вместе с тем не нужно заботиться об освобождении памяти - она будет освобождена автоматически при уничтожении контейнера.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
brb
Дата 12.1.2003, 04:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 190
Регистрация: 7.1.2003

Репутация: нет
Всего: нет



1. Массив поинтеров глобальный, но это действительно не важно.
2. Так как сколько всего мне их надо я не знаю и определяю в цикле, то и new[] использовать не могу.
3. Первоначальный вариант был написан, как бы я делал это через calloc и free на Си, но через new и delete. После нескольких итераций код улетал в никуда...
4. Прочитал в хэлпе:

#include <except.h>
#include <iostream.h>

void display(long double **);
void de_allocate(long double **);

int m = 3;                 // THE NUMBER OF ROWS.
int n = 5;                // THE NUMBER OF COLUMNS.

int main(void) {
  long double **data;

  try {                  // TEST FOR EXCEPTIONS.
     data = new long double*[m];        // STEP 1: SET UP THE ROWS.
     for (int j = 0; j < m; j++)
         data[j] = new long double[n];  // STEP 2: SET UP THE COLUMNS
  }
  catch (xalloc) {  // ENTER THIS BLOCK ONLY IF xalloc IS THROWN.
     // YOU COULD REQUEST OTHER ACTIONS BEFORE TERMINATING
     cout << "Could not allocate. Bye ...";
     exit(-1);
  }
  for (int i = 0; i < m; i++)
     for (int j = 0; j < n; j++)data[i][j] = i + j;// ARBITRARY INITIALIZATION
  display(data);
  de_allocate(data);
  return 0;
}

void display(long double **data) {
  for (int i = 0; i < m; i++) {
     for (int j = 0; j < n; j++)cout << data[i][j] << " ";
     cout << "\n" << endl;
  }
}

void de_allocate(long double **data) {
  for (int i = 0; i < m;  i++)delete[] data[i];// STEP 1: DELETE THE COLUMNS
  delete[] data;           // STEP 2: DELETE THE ROWS !!!!!!!!!!!!!!!!!
}
и сделал так же!!! Заработало.

Обрати внимание и тут new в цикле, а не new[], как ты пишешь!!!
А delete[] я взял в чистом виде.
Хорошо бы это проверить и на другом, не борландовском компиляторе.
--------------------
Сказки - удивительная вещь! Самое удивительное, что в них верят только маленькие дети, которым их рассказывают мамы и мамы, которым их рассказывают подросшие дети.
PM MAIL   Вверх
Fantasist
Дата 12.1.2003, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата
Обрати внимание и тут new в цикле, а не new[]


На самом деле, вот это:
Цитата
data = new long double*[m];

и вот это:
Цитата
data[j] = new long double[n];  

- это new[].

new - это вот так:

data[j][n] = new long double;

Так что, с точки зрения языка вышеприведенный код вполне верен. Разве что new бросает bad_alloc, а не xalloc.

Но повторю еще раз - лучше воспользоваться классами стандартной библиотеки - они весьма эффективны и гораздо понятнее и безопаснее.
Типа так (в простейшем варианте):

Код

#include <vector>
#include <iostream>

typedef vector<vector<long> > longMatrix;

void display(const longMatrix& matrix)
{
 for (int i = 0; i < matrix.size(); i++)
 {
    for (int j = 0; j < matrix[i].size(); j++)cout << matrix[i][j] << " ";
    cout << "\n" << endl;
 }
}

int main()
{
 longMatrix matrix;

 try
 {
   matrix.setsize(m)  
   for (int j = 0; j < m; j++)
     matrix[j].setsize(n);
 }
 catch(bad_alloc)
 { ...  }

 display(matrix);

 return 0;
}
 


Ничего самому освобождать не надо.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
brb
Дата 12.1.2003, 17:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 190
Регистрация: 7.1.2003

Репутация: нет
Всего: нет



во-первых, плохо понял твой пример. С классом матрица не знаком. Завера с утра повторю попытку.
во-вторых, это не ответ на вопрос почему не работает первоначальный код.
в-третьих, а сам попробовал мой код, который не?
Хотелось бы решать проблемы по мере возникновения, а не впрок.

Спасибо.
--------------------
Сказки - удивительная вещь! Самое удивительное, что в них верят только маленькие дети, которым их рассказывают мамы и мамы, которым их рассказывают подросшие дети.
PM MAIL   Вверх
Fantasist
Дата 13.1.2003, 08:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата
С классом матрица не знаком

Это не класс матрицы - это класс массива (vector) мы делаем массив массивов, что не самый классный подход, но лучше, чем просто указатели.

Цитата
это не ответ на вопрос почему не работает первоначальный код.


Потому, что мне не понятно, что значит "не работает". Какие внешние признаки? При просмотре кода все выглядить вполне нормально.

Цитата
в-третьих, а сам попробовал мой код, который не

Это какой "не"? Но в любом случае, код буду пробовать только если очень интересно, а так лень, извините-с.

Цитата
Хотелось бы решать проблемы по мере возникновения, а не впрок


Впрок их решать гораздо лучше. :) Профилактика лучше лечения. Если уж взялись за ООП, надо использовать его по полной программе. Написать хотябы свой простенький класс матрицы. Примерно как здесь.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
brb
Дата 13.1.2003, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 190
Регистрация: 7.1.2003

Репутация: нет
Всего: нет



Про ООП:
Их всех "мочить в сортире" надо как говорит российсктий президент, во главе и в первую очередь с Арафатом!!!:baaa
Про "не"
Вылетает по нарушению памяти после нескольких (3-4) проходов.   :notify
--------------------
Сказки - удивительная вещь! Самое удивительное, что в них верят только маленькие дети, которым их рассказывают мамы и мамы, которым их рассказывают подросшие дети.
PM MAIL   Вверх
Fantasist
Дата 13.1.2003, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата
Вылетает по нарушению памяти после нескольких (3-4) проходов


Я незнаю, насколько полно вы привели кусок кода (да и ошибки такие самому искать надо, с дебаггером) , однако вот тут:

Цитата
for (i = 0; pPayState[i] != NULL; i++ )delete pPayState[i];


Память освобождается, но поинтеры не обнуляются, а значит на каком-то проходе возможно напоротся на не нулевой поинтер, который указывает никуда.

Цитата
Их всех "мочить в сортире" надо как говорит российсктий президент, во главе и в первую очередь с Арафатом!!!


Это к чему? Если вы принципиально не любите ООП, то незачем брать С++, так как Си, на мой взгляд, балее мощьный системный язык.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
brb
Дата 14.1.2003, 00:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 190
Регистрация: 7.1.2003

Репутация: нет
Всего: нет



- фрагменты работы с памятью приведены дословно! Оба.
- это интересно! Т.е. я пытаюсь освободить СВОБОДНУЮ память! Тогда, наверняка, сработает защита памяти.
for (i = 0; pPayState[i] != NULL; i++ ){
  delete pPayState[i];
  pPayState[i] = NULL;
}
Странно, только, что 3-4 прохода, это полный размер pPayState[]. Вот если бы вылетало на втором...

- Попрошу не путать Object Oriented Programming(OOP), с которым я мирно сосуществую, и Организацию Освобождения Палестины(ООП), которую я действительно принципиально не признаю!
А насчет того, что С гораздее, я полностью согласен. Удалено модератором
--------------------
Сказки - удивительная вещь! Самое удивительное, что в них верят только маленькие дети, которым их рассказывают мамы и мамы, которым их рассказывают подросшие дети.
PM MAIL   Вверх
Fantasist
Дата 14.1.2003, 01:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Удалено модератором


--------------------
Волны гасят ветер...
PM MAIL   Вверх
Vit
Дата 14.1.2003, 01:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: нет
Всего: 207



Модератор: Пожалуйста, давайте обсуждать ООП в обоих смыслах во флейме, а целесообразность програмных технологий, если уж тах хочется, то отдельным топиком.


--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
brb
Дата 14.1.2003, 03:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 190
Регистрация: 7.1.2003

Репутация: нет
Всего: нет



С интересом бы прочитал этот коментарий! То, что взгляды не совпадают, явление нормальное, да и шутить тоже не грех, причем, на любую тему!
--------------------
Сказки - удивительная вещь! Самое удивительное, что в них верят только маленькие дети, которым их рассказывают мамы и мамы, которым их рассказывают подросшие дети.
PM MAIL   Вверх
brb
  Дата 27.1.2003, 03:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 190
Регистрация: 7.1.2003

Репутация: нет
Всего: нет



Все замолчали на эту тему, а, по-моему, она не закрыта! Добавлю еще ряд подвопросов.
class PState{}
PState * ps[1200]; // статически выделенная память
for(i = 0; i <1200;i++)ps[i] = new PState ();
/*заполняем предыдущий статический массив динамически*/
/*
какой-то дурацкий код...
*/
delete [ ] ps;
/* похоже, что этот оператор освободит КАЖДЫЙ динамически выделенный элемент массива*/

// Теперь то же, но по-другому

PState **pps = new PState *[1200];
/*кстати, не понятно почему
PState *pps[ ] = new PState *[1200];
выдает ошибку - это же одно и то же!!!*/

for(i = 0; i <1200;i++)pрs[i] = new PState ();
/*заполняем динамический массив динамически*/
/*
еще какой-то дурацкий код...
*/
delete [ ] pps;
/*А что удаляет этот оператор? Массив указателей или и все что внутри тоже?
А может правильно делать так:
for(i = 0; i <1200;i++)delete pрs[i];
delete [ ] pps:
*/

Господа, пожалуйста, делитесь ОПЫТОМ и КОДОМ, а не соображениями.

Спасибо.
--------------------
Сказки - удивительная вещь! Самое удивительное, что в них верят только маленькие дети, которым их рассказывают мамы и мамы, которым их рассказывают подросшие дети.
PM MAIL   Вверх
Fantasist
Дата 29.1.2003, 05:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата
Все замолчали на эту тему, а, по-моему, она не закрыта


Чем же это она не закрыта? На все предыдущие вопросы ответы были данны.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
Fantasist
Дата 29.1.2003, 06:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата
class PState{}
PState * ps[1200]; // статически выделенная память
for(i = 0; i <1200;i++)ps[i] = new PState ();
/*заполняем предыдущий статический массив динамически*/
/*
какой-то дурацкий код...
*/
delete [ ] ps;
/* похоже, что этот оператор освободит КАЖДЫЙ динамически выделенный элемент массива*/


НЕЛЬЗЯ так делать! Я уже об этом говорил. delete[] применим ТОЛЬКО к указателям, для которых память была выделенна с помощью new[] . То, что на вашем компиляторе это может быть работает не означает, что так можно. Если в цикле выделяете, то и в цикле и освобождайте. То есть либо так:

Код

PState * ps[1200]; // статически выделенная память
for(i = 0; i <1200;i++)ps[i] = new PState ();
......
for(i = 0; i <1200;i++) delete ps[i];



либо так:

Код

PState * ps=new PState[1200]; // статически выделенная память
.......
delete [] ps;



Цитата
PState **pps = new PState *[1200];
/*кстати, не понятно почему
PState *pps[ ] = new PState *[1200];
выдает ошибку - это же одно и то же!!!*/


Ничего это не одно и то же, если вы пишите на С++. На мой взгляд, это извращение высшего порядка - в С++ классы есть. А тип PState *[] это не то же самое, что PState **, а то, что они оба реализуются как указатель на указатель, не делают их одним и тем же типом. Это в Java вы можете писать:

Сpd pd[];
pd=new Cpd[10];

В С++ это не так.

Цитата

А может правильно делать так:
for(i = 0; i <1200;i++)delete pрs[i];
delete [ ] pps;


Да. delete[] удаляет массив из нескольких элементов и для каждого из них вызывается деструктор, если тип нетривиальный. В данном случае - это массив указателей - тип тривиальный. Строчкой

delete [ ] pps;

массив указателей будет удален. Объекты, на которые эти указатели указывали никто удалять за вас не будет.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
Guest
Дата 29.1.2003, 07:26 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Уважаемый, Fantasist

С этого все начиналось...

PayState *ptr; // класс поинтер вестимо
PayState *pPayState[1200];

for (i = 0; pPayState[i] != NULL; i++ )delete pPayState[i];
// я думал, что тут я освобождаю всю занятую память
i = 0;
do {
ptr = new PayState ( bc, ic ); // конструктор - аллокирует новую запись
if ( ptr != NULL ){ // успешно
// какой-то дурацкий код...
pPayState[i++] = ptr; //Поместить в массив для дальнейших нужд
}
else {
ShowMessage ("Not enough memory, Sorry");
exit ( EXIT_FAILURE );
}
} while ( ); // больше записей нет!

Я начал эту тему потому что НЕ работало.
Скопированное из хэлпа
delete[ ] pPayState;
прекрасно освобождало память. Это и послужило отправной точкой дискуссии.
Ответа на почему не работало не нашлось, хотя гипотезы и предположения были. Обратите внимание, в НЕработающем коде я делал именно так, как вы настаиваете и я изначально делал.
Цитата
НЕЛЬЗЯ так делать! Я уже об этом говорил. delete[] применим ТОЛЬКО к указателям, для которых память была выделенна с помощью new[] . То, что на вашем компиляторе это может быть работает не означает, что так можно. Если в цикле выделяете, то и в цикле и освобождайте


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

PState **pps = new PState *[1200];
/*кстати, не понятно почему
PState *pps[ ] = new PState *[1200];
выдает ошибку - это же одно и то же!!!*/


Цитата

Ничего это не одно и то же, если вы пишите на С++. На мой взгляд, это извращение высшего порядка - в С++ классы есть. А тип PState *[] это не то же самое, что PState **, а то, что они оба реализуются как указатель на указатель, не делают их одним и тем же типом. Это в Java вы можете писать:

Сpd pd[];
pd=new Cpd[10];

В С++ это не так.


Мы о Джаве не говорим.
А вот
void main(int argc, char *argv[ ]){...}
void main(int argc, char **argv ){...}
Это что не C++? Или что-то из этого не? Или это не одно и тоже?
Не буду утверждать безаппеляционно, как некоторые, но замечу, что по определению [ ](массив) это *(указатель), и если есть
Код

char a[10];
char *p;
p = a; // абсолютно корректно, а  *( p + 5), например,  тоже самое что и a[5]

И причем тут классы? В С++ много чего есть! И при чем тут извращения?
Где сказано, что в ++ указатель на массив какого-либо типа и указатель на указатель того же типа, не одно и тоже? Единственный довод в Вашу пользу, что компилятор выдает ошибку, но это не самый сильный довод.

Цитата

Да. delete[] удаляет массив из нескольких элементов и для каждого из них вызывается деструктор, если тип нетривиальный. В данном случае - это массив указателей - тип тривиальный. Строчкой

delete [ ] pps;

массив указателей будет удален. Объекты, на которые эти указатели указывали никто удалять за вас не будет.


Похоже, что и это не так. Посмотрите опять на самое начало.

И давайте аргументировать, а не бросаться формулами.

С уважением,
BRB
  Вверх
Fantasist
Дата 31.1.2003, 03:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Цитата
Я начал эту тему потому что НЕ работало.
Скопированное из хэлпа
delete[ ] pPayState;
прекрасно освобождало память


Слушайте, а чем вы компилируете? ? ?

Вот код:
Код

              CClass *pClass[1200];

for (int i=0; i<1200; ++i) {pClass[i]=new CClass(i);};

delete[] pClass;



Компилируем VS60. На последнюю строчку получаем:

Цитата
warning C4154: deletion of an array expression; conversion to pointer supplied


При исполнении все грохается на последней строчке, как и следовало ожидать. И это законно - освобождение стековой переменной.

Цитата
Согласен, что некрасиво, но почему то что красиво не согласно со мной?


Ну сколько можно! Это не не красиво, это НЕ ПРАВИЛЬНО по СТАНДАРТУ!

Цитата
но замечу, что по определению [ ](массив) это *(указатель), и если есть


Никогда такого опеределения не было. Поймите, С++ - это не С. Это разные языки, хоть и похожи.
В С++ вы неможете написать:

char p[]=new char[100];

Не можете, и все. Это СТАНДАРТ языка. ТО ЧТО МАССИВ(в реализации) ЯВЛЯЕТСЯ УКАЗАТЕЛЕМ НЕ МЕНЯЕТ ПОЛОЖЕНИЯ.

Удалено модератором


--------------------
Волны гасят ветер...
PM MAIL   Вверх
brb
Дата 31.1.2003, 04:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 190
Регистрация: 7.1.2003

Репутация: нет
Всего: нет



Fantasist
Цитата

Слушайте, а чем вы компилируете? ? ?

Билдером. Был первый, сейчас обзавелся 6-м
Цитата

Компилируем VS60. На последнюю строчку получаем:

Может VC6?
Цитата

Никогда такого опеределения не было. Поймите, С++ - это не С. Это разные языки, хоть и похожи.

C++ это надмножество С. Не верите? Спросите у Страуструпа(фамилию, наверняка, переврал, но все равно узнаваемо), он ++ сочинил!
Цитата

В С++ вы неможете написать:
char p[]=new char[100];

Во-первых, частица НЕ с глаголами пишется раздельно, по крайней мере, на русском языке!
А, во-вторых, хотел бы узнать не то, что это ошибка /* Cannot convert 'char *' to 'char[]'*/, а почему это так!
Цитата

При исполнении все грохается на последней строчке, как и следовало ожидать. И это законно - освобождение стековой переменной.

Массив указателей был объявлен СТАТИЧЕСКИ! Может это причина? Почему же, все-таки первый вариант(внутри цикла до NULL) не работал? И мы именно с Вами это уже обсуждали!
Цитата

for (i = 0; pPayState[i] != NULL; i++ ){
  delete pPayState[i];
  pPayState[i] = NULL;
}
Странно, только, что 3-4 прохода, а это полный размер pPayState[]. Вот если бы вылетало на втором...

Последнее замечание оставленно Вами без ответа.
Тем не менее, от добра добра не ищут, и я оставил все как есть, потому что нет проблем!
Удалено модератором
--------------------
Сказки - удивительная вещь! Самое удивительное, что в них верят только маленькие дети, которым их рассказывают мамы и мамы, которым их рассказывают подросшие дети.
PM MAIL   Вверх
Unregistered
Дата 31.1.2003, 06:45 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Удалено модератором
  Вверх
brb
Дата 31.1.2003, 07:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 190
Регистрация: 7.1.2003

Репутация: нет
Всего: нет



Удалено модератором
--------------------
Сказки - удивительная вещь! Самое удивительное, что в них верят только маленькие дети, которым их рассказывают мамы и мамы, которым их рассказывают подросшие дети.
PM MAIL   Вверх
Fantasist
Дата 31.1.2003, 07:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Удалено модератором

Цитата
А, во-вторых, хотел бы узнать не то, что это ошибка /* Cannot convert 'char *' to 'char[]'*/, а почему это так!


Вот %^&$!! ДА ПОТОМУ ЧТО ЭТО РАЗНЫЕ ТИПЫ ОПРЕДЕЛЕННЫ СТАНТДАРТОМ ЯЗЫКА Mассив - это статический (причем с фиксированным размером!) кусок памяти и все тут. Исключения составляют формальные аргументы функций.

Удалено модератором


--------------------
Волны гасят ветер...
PM MAIL   Вверх
brb
Дата 31.1.2003, 08:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 190
Регистрация: 7.1.2003

Репутация: нет
Всего: нет



Удалено модератором
--------------------
Сказки - удивительная вещь! Самое удивительное, что в них верят только маленькие дети, которым их рассказывают мамы и мамы, которым их рассказывают подросшие дети.
PM MAIL   Вверх
Vit
Дата 31.1.2003, 09:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: нет
Всего: 207



Модератор: ещё не забыли о чём спрашивалось в теме? Напоминаю -

Цитата
объясните в чем дело? Я и синтаксиса такого не знаю: delete[] pPayState;


2 brb: если на вопрос отвечено, то я тему закрываю, если нет, то спрашивайте по существу чтО именно не понятно.

2 Fantasist: Давайте без перехода на личности


--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
Fantasist
Дата 31.1.2003, 09:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: 4
Всего: 41



Удалено модератором


--------------------
Волны гасят ветер...
PM MAIL   Вверх
brb
Дата 31.1.2003, 09:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 190
Регистрация: 7.1.2003

Репутация: нет
Всего: нет



Vit
Считаю действия модератора не вполне корректными. Лозунг "Уважайте труд уборщиц" к действиям
Цитата
Удалено модератором
не подходит.
Продолжаю считать губость и хамство недопустимыми, даже если кому-то и хочется поругаться.
Давайте писать грамотно чтобы ляпов типа
Цитата
балее мощьный системный язык.
не было. Знание языков программирования НЕ освобождает от знания родного языка!


--------------------
Сказки - удивительная вещь! Самое удивительное, что в них верят только маленькие дети, которым их рассказывают мамы и мамы, которым их рассказывают подросшие дети.
PM MAIL   Вверх
Vit
Дата 31.1.2003, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: нет
Всего: 207



Модератор: Обсуждение модераторов и правомерности их действий проводится в разделе обсуждение форума. О моих действиях Вы можете отзываться как угодно, но я удалил только те высказывания, которые не имели никакого отношения к обсуждению заданного вопроса. Я что-то не понял, чем Вас не устроило моё модерирование, ведь Вы написали о том что по отношению к Вам были проявлены "губость и хамство" - я удалил все такие замечания, кроме того я удалил все рассуждения которые выходили за рамки заданного вопроса, я сделал личное замечание Fantasist'у о недопустимости таких высказываний. Считаю эти меры достаточными, но если в этот раздел попадёт хоть ещё одна фраза не относящаяся к программированию на C/C++ от Fantasist или Brb, то топик будет закрыт.

Теперь, я указал в своём сообщении, что пора бы прекратить пререкания и обсуждения личностей, и вообще все вопросы не связанные с темой топика. Оба оппонента не вняли предупреждению и продолжается обсуждение непонятно чего! Ещё раз повторюсь, здесь обсуждается программирование на С и С++ и среды разработки програм на С/С++. Обсуждение любых других тем, в том числе других участников, действий модератора и грамотность языка в этом разделе категорически запрещено. Пожалуйста - всё это Вы можете делать в разделах о форуме и флейме.



--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0761 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.