Динамические массивы, освобождение памяти
От: piero_  
Дата: 15.02.08 21:39
Оценка:
как освободить память, если у меня 4-мерный динамический массив, выделяю память я так:
 int **** Grid11;
 int Range1, Range2;

 Grid11 = new int***[Range1];
  for(i1 = 0; i1 < Range1; i1++)
  {Grid11[i1] = new int**[Range1];
   for(i2 = 0; i2 < Range1; i2++)
   {Grid11[i1][i2] = new int*[Range2];
    for(i3 = 0; i3 < Range2; i3++)
    {Grid11[i1][i2][i3] = new int[Range2];
     memset(Grid11[i1][i2][i3],0, sizeof(int)*(Range2));
    }
   }
  }

Спасибо
Добавлена разметка — Кодт
Re: Динамические массивы, освобождение памяти
От: Sni4ok  
Дата: 15.02.08 22:02
Оценка: -3
Здравствуйте, piero_, Вы писали:

_>как освободить память, если у меня 4-мерный динамический массив, выделяю память я так:


_> int **** Grid11;

_> int Range1, Range2;

_> Grid11 = new int***[Range1];

_> for(i1 = 0; i1 < Range1; i1++)
_> {Grid11[i1] = new int**[Range1];
_> for(i2 = 0; i2 < Range1; i2++)
_> {Grid11[i1][i2] = new int*[Range2];
_> for(i3 = 0; i3 < Range2; i3++)
_> {Grid11[i1][i2][i3] = new int[Range2];
_> memset(Grid11[i1][i2][i3],0, sizeof(int)*(Range2));
_> }
_> }
_> }

_>Спасибо


а никак- ибо приведённый код уже не удовлетворяет базовой гарантии, поэтому можете и не рыпаться.
Re: Динамические массивы, освобождение памяти
От: Erop Россия  
Дата: 15.02.08 22:41
Оценка: 1 (1) -1
Здравствуйте, piero_, Вы писали:

1) пользуйся тэгами [c][/c] для оформления кода!!!

int **** Grid11;
int Range1, Range2;

Grid11 = new int***[Range1];
for(i1 = 0; i1 < Range1; i1++)
{
    Grid11[i1] = new int**[Range1]; 
    for(i2 = 0; i2 < Range1; i2++)
    {
         Grid11[i1][i2] = new int*[Range2];
         for(i3 = 0; i3 < Range2; i3++)
         {
             Grid11[i1][i2][i3] = new int[Range2];
             memset(Grid11[i1][i2][i3],0, sizeof(int)*(Range2));
         }
    }
}


2) Если есть шанс, что памяти не хватит, то стоит использовать new(nothrow) int**[Range1] ну и т. д.
И проверять что указатели не 0
bool is_no_memory = false;
Grid11 = new(nothrow) int***[Range1];
if( Grid11 == 0 ) {
    is_no_memory = true;
} else {
    for(i1 = 0; i1 < Range1; i1++)
    {
       Grid11[i1] = new(nothrow) int**[Range1]; 
       if( Grid11[i1] == 0 ) {
           is_no_memory = true;
           continue;
       }
       for(i2 = 0; i2 < Range1; i2++)
       {
            Grid11[i1][i2] = new(nothrow) int*[Range2];
            if( Grid11[i1][i2] == 0 ) {
                is_no_memory = true;
                continue;
            }
            for(i3 = 0; i3 < Range2; i3++)
            {
                Grid11[i1][i2][i3] = new(nothrow) int[Range2];
                if( Grid11[i1][i2][i3] == 0 ) {
                   is_no_memory = true;
                   continue;
               }
                memset(Grid11[i1][i2][i3],0, sizeof(int)*(Range2));
            }
       }
   }
}


ну и освобождаешь в "обратном порядке"
if( Grid11 != 0 ) {
    for( int i1 = 0; i < Range1; i1++ ) {
        if( Grid11х[i1] == 0 )
            continue;
        for( int i2 = 0; i2 < Range2; i2++ ) {
            if( Grid11х[i1][i2] == 0 )
                continue;
            for( int i3 = 0; i3 < Range3; i3++ ) {
                if( Grid11х[i1][i2][i3] == 0 )
                    continue;
                delete [] Grid11х[i1][i2][i3];
            }
            delete [] Grid11х[i1][i2];
        }
        delete [] Grid11х[i1];
    }
}


3) Только на С++ так писать не модно. Модно какую-нибудь библиотеку куонтейнеров использовать. За неимением лучшей можно использовать STL, например.

Скажем так:
typedef std::vector<int> TLine;
TLine line( 0, Range3 );
typedef std::vector<TLine> TMatrix;
TMatrix matrix( line, Range2 );
// и т. д.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Динамические массивы, освобождение памяти
От: ilnar Россия  
Дата: 15.02.08 23:03
Оценка: +1
Здравствуйте, piero_, Вы писали:

_>как освободить память, если у меня 4-мерный динамический массив, выделяю память я так:


_> int **** Grid11;

_> int Range1, Range2;

_> Grid11 = new int***[Range1];

_> for(i1 = 0; i1 < Range1; i1++)
_> {Grid11[i1] = new int**[Range1];
_> for(i2 = 0; i2 < Range1; i2++)
_> {Grid11[i1][i2] = new int*[Range2];
_> for(i3 = 0; i3 < Range2; i3++)
_> {Grid11[i1][i2][i3] = new int[Range2];
_> memset(Grid11[i1][i2][i3],0, sizeof(int)*(Range2));
_> }
_> }
_> }

_>Спасибо


ответ будет не по теме: хорошо бы нормально форматировать и включать в теги [ ccode ] там внизу
Re[2]: и чито не так?
От: Erop Россия  
Дата: 16.02.08 00:43
Оценка:
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: С чем не согласен я
От: Erop Россия  
Дата: 16.02.08 00:45
Оценка: +2 -1
Здравствуйте, Sni4ok, Вы писали:

S>а никак- ибо приведённый код уже не удовлетворяет базовой гарантии, поэтому можете и не рыпаться.


1) с хамской формой ответа
2) Вообщето спрашивали о том, как память освободить, а не о гарантиях (видимо exception safety)...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Динамические массивы, освобождение памяти
От: Анатолий Широков СССР  
Дата: 16.02.08 09:35
Оценка:
Здравствуйте, piero_, Вы писали:

_>как освободить память, если у меня 4-мерный динамический массив, выделяю память я так:


В порядке обратном выделению, то есть такой же цикл:

int **** Grid11;
int Range1, Range2;
...
Grid11 = new int***[Range1];
for(i1 = 0; i1 < Range1; i1++) {
   for(i2 = 0; i2 < Range1; i2++) {
       for(i3 = 0; i3 < Range2; i3++) {
          delete [] Grid11[i1][i2][i3];
       } 
       delete [] Grid11[i1][i2];
   }
   delete [] Grid11[i1];
}
delete [] Grid11;
Re: Динамические массивы, освобождение памяти
От: rg45 СССР  
Дата: 16.02.08 09:59
Оценка: +1
Здравствуйте, piero_, Вы писали:

_>как освободить память, если у меня 4-мерный динамический массив, выделяю память я так:


_> int **** Grid11;

_> int Range1, Range2;

_> Grid11 = new int***[Range1];

_> for(i1 = 0; i1 < Range1; i1++)
_> {Grid11[i1] = new int**[Range1];
_> for(i2 = 0; i2 < Range1; i2++)
_> {Grid11[i1][i2] = new int*[Range2];
_> for(i3 = 0; i3 < Range2; i3++)
_> {Grid11[i1][i2][i3] = new int[Range2];
_> memset(Grid11[i1][i2][i3],0, sizeof(int)*(Range2));
_> }
_> }
_> }

_>Спасибо


Ответ Егора хочу дополнить подсказкой. Если в этом примере использовать класс std::vector из стандартной библиотеки, то забота об освобождении памти отпадает автоматически:
#include <iostream>
#include <vector>

int main()
{
  using namespace std;

  typedef vector<int> V1;
  typedef vector<V1> V2;
  typedef vector<V2> V3;
  typedef vector<V3> V4;

  int Range1 = 20, Range2 = 10;

  //Создаем четырехмерный массив целых, заполненный нулями.
  V4 Grid11(Range1, V3(Range1, V2(Range2, V1(Range1)))); 

  //Создаем такой же четырехмерный массив, заполненный единицами.
  V4 Grid22(Range1, V3(Range1, V2(Range2, V1(Range1, 1)))); 

  //Работаем, как с обычными встроенными массивами
  Grid11[1][2][3][4] = 1234; 
  Grid22[4][3][2][1] = 4321; 
  
  cout << Grid11[1][2][3][4] << endl;
  cout << Grid22[4][3][2][1] << endl;

  /*...*/
}


При выходе из функции main память, выделенная для объектов Grid11 и Grid22, будет освобождена автоматически. Кроме того, твой код приобрет устойчивость по отношению к возможным исключениям — память освободится даже в этом случае. И, что очень важно, сравни эти два варианта кода, какой из них легче прочитать и проще понять?
... << RSDN@Home 1.2.0 alpha rev. 787>>
--
Справедливость выше закона. А человечность выше справедливости.
Re[2]: Динамические массивы, освобождение памяти
От: Аноним  
Дата: 16.02.08 16:12
Оценка:
спасибо за ответы, постараюсь учесть ваши замечания
Re[2]: Динамические массивы, освобождение памяти
От: -MyXa- Россия  
Дата: 16.02.08 17:19
Оценка: +1 :)
Здравствуйте, rg45, Вы писали:

[поскипано]

Или можно Boost.MultiArray поюзать.
Если не поможет, будем действовать током... 600 Вольт (C)
Re[2]: Динамические массивы, освобождение памяти
От: Аноним  
Дата: 17.02.08 11:06
Оценка:
Здравствуйте, rg45, Вы писали:

R>Ответ Егора хочу дополнить подсказкой. Если в этом примере использовать класс std::vector из стандартной библиотеки, то забота об освобождении памти отпадает автоматически:

R>
R>#include <iostream>
R>#include <vector>

R>int main()
R>{
R>  using namespace std;

R>  typedef vector<int> V1;
R>  typedef vector<V1> V2;
R>  typedef vector<V2> V3;
R>  typedef vector<V3> V4;

R>  int Range1 = 20, Range2 = 10;

R>  //Создаем четырехмерный массив целых, заполненный нулями.
R>  V4 Grid11(Range1, V3(Range1, V2(Range2, V1(Range1)))); 

R>  //Создаем такой же четырехмерный массив, заполненный единицами.
R>  V4 Grid22(Range1, V3(Range1, V2(Range2, V1(Range1, 1)))); 

R>  //Работаем, как с обычными встроенными массивами
R>  Grid11[1][2][3][4] = 1234; 
R>  Grid22[4][3][2][1] = 4321; 
  
R>  cout << Grid11[1][2][3][4] << endl;
R>  cout << Grid22[4][3][2][1] << endl;

R>  /*...*/
R>}
R>


R>При выходе из функции main память, выделенная для объектов Grid11 и Grid22, будет освобождена автоматически. Кроме того, твой код приобрет устойчивость по отношению к возможным исключениям — память освободится даже в этом случае. И, что очень важно, сравни эти два варианта кода, какой из них легче прочитать и проще понять?



Я сделал как вы сказали, но не могу обратиться к элементу Grid11[0][0][0][0]
дебагер говорит "2382 Side effects are not allowed"
??? в чем может быть ошибка?
Re[3]: Динамические массивы, освобождение памяти
От: rg45 СССР  
Дата: 17.02.08 12:07
Оценка: +1
Здравствуйте, <Аноним>, Вы писали:

А>Я сделал как вы сказали, но не могу обратиться к элементу Grid11[0][0][0][0]

А>дебагер говорит "2382 Side effects are not allowed"
А>??? в чем может быть ошибка?

Где отображается сообщение: "2382 Side effects are not allowed"? Правильно я понимаю, что программа компилируется и запускается, но не получается увидеть значение Grid11[0][0][0][0] при прассировке программы в отлдадчике?
... << RSDN@Home 1.2.0 alpha rev. 787>>
--
Справедливость выше закона. А человечность выше справедливости.
Re[4]: Динамические массивы, освобождение памяти
От: piero_  
Дата: 17.02.08 12:20
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, <Аноним>, Вы писали:


А>>Я сделал как вы сказали, но не могу обратиться к элементу Grid11[0][0][0][0]

А>>дебагер говорит "2382 Side effects are not allowed"
А>>??? в чем может быть ошибка?

R>Где отображается сообщение: "2382 Side effects are not allowed"? Правильно я понимаю, что программа компилируется и запускается, но не получается увидеть значение Grid11[0][0][0][0] при прассировке программы в отлдадчике?


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

R>Здравствуйте, <Аноним>, Вы писали:


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


А>>Я сделал как вы сказали, но не могу обратиться к элементу Grid11[0][0][0][0]

А>>дебагер говорит "2382 Side effects are not allowed"
А>>??? в чем может быть ошибка?

R>Несколько вопросов:

R>- какой компилятор?
R>- компилируется ли пример в том виде, в котором привел его я?
R>- приведи полный текст модуля(cpp-файла), при компиляции которого возникает ошибка

у меня C++ Builder 6, а какой в ней компилятор — не знаю
да компилируется,
я использую этот массив в классе, полный текст приводить не буду — очень длинно, но в краце так:


--------------------------------------------------

cens.h:

...
using namespace std;

typedef vector<int> V1;
typedef vector<V1> V2;
typedef vector<V2> V3;
typedef vector<V3> V4;

class TCENS
{
...
public:
  V4 Q2;
...
}



----------------------------------------------------

cens.cpp

int TCENS::Init()
{
 ...
 int g1 = 11;
 int g2 = 41;
 
 V4 Q2(g1, V3(g1, V2(g2, V1(g2,0)))); 
 int m = Q2[0][0][0][0];  // здесь ошибки нет, но если включить окно "watch list", то там вместо значения Q2[0][0][0][0] сообщение - "E2384 Side effects are not allowed" 
 ...
}


int TCENS::DoOneStep()
{
 ...
 Q2[i1][i2][i3][i4] += hr;   // здесь происходит ошибка при первом проходе т.е. i1=i2=i3=i4=0
 ...
}



извините что без тэгов, что-то я не понял как выделять текст нужным цветом
Re[5]: Динамические массивы, освобождение памяти
От: rg45 СССР  
Дата: 17.02.08 12:45
Оценка: +1
Здравствуйте, piero_, Вы писали:

_>у меня C++ Builder 6, а какой в ней компилятор — не знаю

Ну значит, компилятор — C++ Builder 6

_>да компилируется,

_>я использую этот массив в классе, полный текст приводить не буду — очень длинно, но в краце так:
_>
_>//...
_> int m = Q2[0][0][0][0];  // здесь ошибки нет, но если включить окно "watch list", то там вместо значения Q2[0][0][0][0] сообщение - "E2384 Side effects are not allowed" 
_>//...
_>


Выходит, что среда C++ Builder'a не умеет вычислять значения функций. Ведь, на самом деле, в приведенном примере операция индексирования сводится к вызову перегруженного оператора operator[], который по сути является функцией-членом шаблонного класса std::vector. Что делать в этой ситуации? Зависит от того, на сколько критичным для тебя является это неудобство.
Возможные варианты действий:
— Забить на это;
— Заглянуть в отладчике внутрь объекта Q2 — внутри находятся самые обычные указатели, которые отладчик билдера, наверняка, умеет отображать;
— Выводить все интересующие значения на экран, в файл и т.д.;
— Сменить компилятор и среду разработки. Например, на Microsoft Visual Studio.

_>извините что без тэгов, что-то я не понял как выделять текст нужным цветом

Просто ты немного ошибся с выбором тэга форматирования: ты использовал code, а нужно было ccode.
... << RSDN@Home 1.2.0 alpha rev. 787>>
--
Справедливость выше закона. А человечность выше справедливости.
Re[2]: Динамические массивы, освобождение памяти
От: tilarids Украина tilarids.blogspot.com
Дата: 18.02.08 13:47
Оценка: 1 (1)
Здравствуйте, rg45, Вы писали:

R>
R>#include <iostream>
R>#include <vector>

R>int main()
R>{
R>  using namespace std;

R>  typedef vector<int> V1;
R>  typedef vector<V1> V2;
R>  typedef vector<V2> V3;
R>  typedef vector<V3> V4;

R>  int Range1 = 20, Range2 = 10;

R>  //Создаем четырехмерный массив целых, заполненный нулями.
R>  V4 Grid11(Range1, V3(Range1, V2(Range2, V1(Range1)))); 

R>  //Создаем такой же четырехмерный массив, заполненный единицами.
R>  V4 Grid22(Range1, V3(Range1, V2(Range2, V1(Range1, 1)))); 

R>  //Работаем, как с обычными встроенными массивами
R>  Grid11[1][2][3][4] = 1234; 
R>  Grid22[4][3][2][1] = 4321; 
  
R>  cout << Grid11[1][2][3][4] << endl;
R>  cout << Grid22[4][3][2][1] << endl;

R>  /*...*/
R>}
R>

А вот так:
template <typename FirstClass, size_t i>
class MegaVector
{
public:
    typedef typename MegaVector<FirstClass,i-1>::type innerType;
    typedef std::vector<innerType> type;
};

template <typename FirstClass>
class MegaVector<FirstClass,0>
{
public:
    typedef FirstClass type;
};

int main()
{
    using namespace std;
    typedef MegaVector<int,4>::type V4;
    //...

Так красивше, мне кажется
Я пробовал более общно написать(не завязываться на векторе), но что-то мой компилятор ругается, когда я использую передаваемый тип, как шаблон. Если не найду, в чём проблема, — придётся создавать отдельную тему об этом
<вырезано, дабы сохранить место на сервере>
Re[3]: Динамические массивы, освобождение памяти
От: rg45 СССР  
Дата: 18.02.08 21:43
Оценка:
Здравствуйте, tilarids, Вы писали:

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


T>А вот так:

T>
T>template <typename FirstClass, size_t i>
T>class MegaVector
T>{
T>public:
T>    typedef typename MegaVector<FirstClass,i-1>::type innerType;
T>    typedef std::vector<innerType> type;
T>};

T>template <typename FirstClass>
T>class MegaVector<FirstClass,0>
T>{
T>public:
T>    typedef FirstClass type;
T>};

T>int main()
T>{
T>    using namespace std;
T>    typedef MegaVector<int,4>::type V4;
T>    //...
T>

T>Так красивше, мне кажется
T>Я пробовал более общно написать(не завязываться на векторе), но что-то мой компилятор ругается, когда я использую передаваемый тип, как шаблон. Если не найду, в чём проблема, — придётся создавать отдельную тему об этом

Нечто подобное и я хотел написать. Но потом решил, что во-первых, тогда уж лучше действительно, как предлагали выше, использовать boost::multi_array. А во-вторых, автору вопроса на первое время информации для переваривания достаточно и без шаблонов
... << RSDN@Home 1.2.0 alpha rev. 787>>
--
Справедливость выше закона. А человечность выше справедливости.
Re[5]: Динамические массивы, освобождение памяти
От: Владик Россия  
Дата: 20.02.08 20:29
Оценка:
Здравствуйте, piero_, Вы писали:

_>int TCENS::Init()

_>{
_> ...
_> V4 Q2(g1, V3(g1, V2(g2, V1(g2,0))));

Здесь ты проинитил локальную переменную Q2.

_>int TCENS::DoOneStep()

_>{
_> ...
_> Q2[i1][i2][i3][i4] += hr; // здесь происходит ошибка при первом проходе т.е. i1=i2=i3=i4=0

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