Форум программистов, компьютерный форум CyberForum.ru

Деструктор для массива матриц... - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 27, средняя оценка - 4.74
Vladd
0 / 0 / 0
Регистрация: 25.10.2009
Сообщений: 11
25.10.2009, 17:37     Деструктор для массива матриц... #1
Помогите написать деструктор для массива матриц.. Деструктор для матрицы вроде бы вот так пишется:
C++
1
2
3
4
5
{
    for (int z = 0; z < _rows; ++z)
        delete[] _matrix[z];
    delete[] _matrix;
}
А вот для массива матриц я не знаю Была вот такая идея:
C++
1
2
3
4
{
    for (int i = 0; i < _masDimension; ++i)
    _arrayOfMatrix[i].~Matrix();
}
Но компилятор ужасно злится, а потом программа вылетает..
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
niXman
Эксперт C++
 Аватар для niXman
3133 / 1445 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
25.10.2009, 17:58     Деструктор для массива матриц... #2
Vladd, Для начала, покажи кто такой
Цитата Сообщение от Vladd Посмотреть сообщение
Matrix
M128K145
Эксперт C++
 Аватар для M128K145
8272 / 3491 / 142
Регистрация: 03.07.2009
Сообщений: 10,707
25.10.2009, 18:38     Деструктор для массива матриц... #3
попробуй
так
C++
1
2
3
4
5
6
7
for (int i = 0; i < _masDimension; ++i)
{
    for (int z = 0; z < _rows; ++z)
        delete[] _matrix[z][i];
    delete[] _matrix[i];
}
delete[] _arrayOfMatrix;
Vladd
0 / 0 / 0
Регистрация: 25.10.2009
Сообщений: 11
26.10.2009, 19:42  [ТС]     Деструктор для массива матриц... #4
Цитата Сообщение от M128K145 Посмотреть сообщение
попробуй
так
C++
1
2
3
4
5
6
7
for (int i = 0; i < _masDimension; ++i)
{
    for (int z = 0; z < _rows; ++z)
        delete[] _matrix[z][i];
    delete[] _matrix[i];
}
delete[] _arrayOfMatrix;
Попробовал, пишет что _matrix необъявленный идентификатор... Я подумал, что может у меня создание неправильно реализовано.. В общем вот код:

Matrix.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Matrix
{
private:
    int** _matrix;
    int _rows, _cols;
 
    void Create();
    void Filling();
 
public:
    Matrix();
    Matrix(int i);
    Matrix(int i, int j);
    Matrix(const Matrix&);
 
    ~Matrix();
};

Matrix.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void Matrix::Create()
{
    _matrix = new int*[_rows];
    for (int z = 0; z < _rows; z++)
    _matrix[z] = new int[_cols];
}
 
void Matrix::Filling()
{
    srand(time(NULL));
    for (int i = 0; i < _rows; ++i)
    for (int j = 0; j < _cols; ++j)
        _matrix[i][j] = rand()%10;
}
 
Matrix::Matrix():_rows(5), _cols(5) { Create(), Filling(); }
 
Matrix::Matrix(int i): _rows(i), _cols(i) { Create(); Filling(); }
 
Matrix::Matrix(int rows, int cols): _rows(rows), _cols(cols) { Create(); Filling(); }
 
Matrix::Matrix(const Matrix& m)         
{
    _rows = m._rows;
    _cols = m._cols;
    Create();
    for (int i = 0; i < _rows; ++i)
        for (int j = 0; j < _cols; ++j)
            _matrix[i][j] = m._matrix[i][j];
}
 
Matrix::~Matrix()
{
    for (int z = 0; z < _rows; z++)
        delete[] _matrix[z];
    delete[] _matrix;
}

ArrayOfMatrix.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class ArrayOfMatrix
{
    private:
    Matrix* _arrayOfMatrix;
    int _masDimension;
    int _rows, _cols;
    void Create ();
    Matrix Creator();
        
    public:
    ArrayOfMatrix(int, int, int);           // 1ое число: размер массива, 2ое и 3ье: размеры матрицы
 
    ~ArrayOfMatrix();
}

ArrayOfMatrix.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void ArrayOfMatrix::Create()
{
    _arrayOfMatrix = new Matrix[_masDimension];
    for (int i = 0; i < _masDimension; ++i)
    _arrayOfMatrix[i] = Creator();
}
 
Matrix ArrayOfMatrix::Creator()
{
    Matrix obj;
    return obj;
}
 
ArrayOfMatrix::ArrayOfMatrix(int masDimension, int rows, int cols) 
{   
    _rows = rows;
    _cols = cols;
    _masDimension = masDimension;
    Create();
}
 
ArrayOfMatrix::~ArrayOfMatrix()
{
    for (int i = 0; i < _masDimension; ++i)
    {
        for (int z = 0; z < _rows; ++z)
        delete[] _matrix[z][i];
        delete[] _matrix[i];
    }
    delete[] _arrayOfMatrix;
}

Не спрашивайте почему я так модно создаю массив матриц Зато сам придумал
Vladd
0 / 0 / 0
Регистрация: 25.10.2009
Сообщений: 11
27.10.2009, 16:57  [ТС]     Деструктор для массива матриц... #5
Скажите пож-та на что вообще указывает указатель массива матриц? На элемент [0][0]?
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,135
Записей в блоге: 26
27.10.2009, 19:32     Деструктор для массива матриц... #6
Ели ты про поле _arrayOfMatrix, то на _arrayOfMatrix[0], которое ты выделил через new
M128K145
Эксперт C++
 Аватар для M128K145
8272 / 3491 / 142
Регистрация: 03.07.2009
Сообщений: 10,707
27.10.2009, 23:12     Деструктор для массива матриц... #7
C++
1
2
3
4
5
6
7
ArrayOfMatrix::~ArrayOfMatrix()
{
    int i;
    for(i = 0; i < _masDimension; ++i)
        _arrayOfMatrix[i].~Matrix();
    delete[] _arrayOfMatrix;
}
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,135
Записей в блоге: 26
27.10.2009, 23:21     Деструктор для массива матриц... #8
Конструктор и деструктор - это НЕ функции, а потому вызывать их нельзя
Даемоник
 Аватар для Даемоник
41 / 41 / 3
Регистрация: 22.05.2009
Сообщений: 97
27.10.2009, 23:33     Деструктор для массива матриц... #9
Цитата Сообщение от Vladd Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
ArrayOfMatrix::~ArrayOfMatrix()
{
 for (int i = 0; i < _masDimension; ++i)
 {
 for (int z = 0; z < _rows; ++z)
 delete[] _matrix[z][i];
 delete[] _matrix[i];
 }
 delete[] _arrayOfMatrix;
По-моему в этом куске надо поменять местами i и z(в строке delete[] _matrix[z][i]), потому что получается ты удаляешь из каждой строки элемент соответствующий значению i, а не z.
M128K145
Эксперт C++
 Аватар для M128K145
8272 / 3491 / 142
Регистрация: 03.07.2009
Сообщений: 10,707
27.10.2009, 23:57     Деструктор для массива матриц... #10
Evg, я тоже слышал такое утверждение, но все же объясни тогда пожалуйста такое явление
код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
class test
{
    int a;
    public:
    test();
    ~test();
};
test::test()
{
    a = 5;
    std::cout<<"создан\na = "<<a<<std::endl;
}
test::~test()
{
    a = NULL;
    std::cout<<"удален\na = "<<a<<std::endl;
}
int main()
{
    setlocale(LC_ALL, "Russian");
 
    test* ts1 = new test();
    delete ts1;
 
    test* ts2 = new test();
    ts2->~test();
 
    system("pause");
    return 0;
}

результат
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,135
Записей в блоге: 26
28.10.2009, 00:10     Деструктор для массива матриц... #11
Я фигею... на gcc работает, на борланде работает.... Более того, на деструктор разрешается брать адрес (на конструктор - нет). Интересная штука, надо этот вопрос поизучать
Vladd
0 / 0 / 0
Регистрация: 25.10.2009
Сообщений: 11
28.10.2009, 06:47  [ТС]     Деструктор для массива матриц... #12
Цитата Сообщение от M128K145 Посмотреть сообщение
C++
1
2
3
4
5
6
7
ArrayOfMatrix::~ArrayOfMatrix()
{
    int i;
    for(i = 0; i < _masDimension; ++i)
        _arrayOfMatrix[i].~Matrix();
    delete[] _arrayOfMatrix;
}
Выдаёт вот это и программа вылетает
Необработанное исключение типа "System.AccessViolationException" произошло в ArrayOfMatrix.exe
Дополнительные сведения: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.

Добавлено через 2 минуты
Цитата Сообщение от Даемоник Посмотреть сообщение
По-моему в этом куске надо поменять местами i и z(в строке delete[] _matrix[z][i]), потому что получается ты удаляешь из каждой строки элемент соответствующий значению i, а не z.
Пишет: error C2065: _matrix: необъявленный идентификатор
M128K145
Эксперт C++
 Аватар для M128K145
8272 / 3491 / 142
Регистрация: 03.07.2009
Сообщений: 10,707
28.10.2009, 07:40     Деструктор для массива матриц... #13
Vladd, скинь код мейна
Vladd
0 / 0 / 0
Регистрация: 25.10.2009
Сообщений: 11
28.10.2009, 08:39  [ТС]     Деструктор для массива матриц... #14
Цитата Сообщение от M128K145 Посмотреть сообщение
Vladd, скинь код мейна
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#include "ArrayOfMatrix.h"
#include "Matrix.h"
 
using namespace std;
 
void main()
{
    ArrayOfMatrix m1(3,5,5);
    cout << m1[1] << endl;
    getch();
}
Без деструктора всё нормально работает, но мне надо учителю доказать что здесь будет композиция, т.е. времена жизни объектов Матрикс и АррОфМатрикс одинаковы.. Вот я и парюсь с деструктором... Оператор << перегружен и выдаёт всё нормально..
C++
1
2
3
4
5
6
7
8
9
10
 std::ostream& operator<<(std::ostream& out, const Matrix& object )
 {
    for( int i=0; i<object._rows; ++i )
    {
        for( int j=0; j<object._cols; ++j )
            out << object._matrix[i][j] << " ";
        out << std::endl;
    }
    return out;
 }
Мне кажется что я коряво как-то создаю массив матриц...
C++
1
2
3
4
5
6
7
8
9
10
11
12
void ArrayOfMatrix::Create()
{
    _arrayOfMatrix = new Matrix[_masDimension];
    for (int i = 0; i < _masDimension; ++i)
        _arrayOfMatrix[i] = Creator();
}
 
Matrix ArrayOfMatrix::Creator()
{
    Matrix obj;
    return obj;
}
Может есть другой метод?
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,135
Записей в блоге: 26
28.10.2009, 16:22     Деструктор для массива матриц... #15
С деструктораи ситуация следующая. В стандарте действительно их можно вызывать. При этом в момент удаления объекта он всё равно будет вызван

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream.h>
 
class T
{
  public:
    T() { cout << "constr\n"; }
    ~T() { cout << "destr\n"; }
};
 
int main (void)
{
  T t;
  t.~T();
}
Код
constr
destr
destr
В стандарте описывается единственный случай, когда это нужно делать - это если мы вызывали new с указанием места в памяти, где выделать объект. Ибо в этом случае получается, что нельзя вызывать delete на объект, поэтому оставили способ, чтобы вызвать деструктор. Во всех остальных случаях поведение неопределено. Поэтому в данном случае так вызывать деструктор нельзя

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream.h>
 
class T
{
    int x;
  public:
    T() { cout << "constr\n"; }
    ~T() { cout << "destr\n"; }
};
 
int main (void)
{
  char *buf = new char[sizeof(T)];
  T *t = new(buf) T;
  
  t->~T();
}
Vladd
0 / 0 / 0
Регистрация: 25.10.2009
Сообщений: 11
28.10.2009, 19:33  [ТС]     Деструктор для массива матриц... #16
Цитата Сообщение от Evg Посмотреть сообщение
С деструктораи ситуация следующая. В стандарте действительно их можно вызывать. При этом в момент удаления объекта он всё равно будет вызван

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream.h>
 
class T
{
  public:
    T() { cout << "constr\n"; }
    ~T() { cout << "destr\n"; }
};
 
int main (void)
{
  T t;
  t.~T();
}
Код
constr
destr
destr
В стандарте описывается единственный случай, когда это нужно делать - это если мы вызывали new с указанием места в памяти, где выделать объект. Ибо в этом случае получается, что нельзя вызывать delete на объект, поэтому оставили способ, чтобы вызвать деструктор. Во всех остальных случаях поведение неопределено. Поэтому в данном случае так вызывать деструктор нельзя

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream.h>
 
class T
{
    int x;
  public:
    T() { cout << "constr\n"; }
    ~T() { cout << "destr\n"; }
};
 
int main (void)
{
  char *buf = new char[sizeof(T)];
  T *t = new(buf) T;
  
  t->~T();
}
Эм.. А мне то что делать? У меня есть new... Как деструктор правильно написать?
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,135
Записей в блоге: 26
28.10.2009, 20:44     Деструктор для массива матриц... #17
Ты хоть покажи всю программу целиком, а не куски-огрызки. И ткни пальцем в место, где возникает вопрос. Из прошлых объяснений я, например, не понял ничего
Vladd
0 / 0 / 0
Регистрация: 25.10.2009
Сообщений: 11
29.10.2009, 05:15  [ТС]     Деструктор для массива матриц... #18
Цитата Сообщение от Evg Посмотреть сообщение
Ты хоть покажи всю программу целиком, а не куски-огрызки. И ткни пальцем в место, где возникает вопрос. Из прошлых объяснений я, например, не понял ничего
В программе меня волнует только деструктор, у меня его пока что нету... Вся программа это Matrix.h, Matrix.cpp, ArrayOfMatrix.h, ArrayOfMatrix.cpp, Main.cpp. 1ые 4 файла я написал в одном сообщении, а мэйн пойзже... Просто не вижу смысла снова всё вставлять. Зачем засорять тему?
Вот самые популярные предложения по поводу того как организовать деструктор:
Вот так
C++
1
2
3
4
5
6
7
8
9
10
ArrayOfMatrix::~ArrayOfMatrix()
{
    for (int i = 0; i < _masDimension; ++i)
    {
        for (int z = 0; z < _rows; ++z)
            delete[] _matrix[i][z];
        delete[] _matrix[i];
    }
    delete[] _arrayOfMatrix;
}
Но тогда выдаёт error C2065: _matrix: необъявленный идентификатор.

Либо вот так
C++
1
2
3
4
5
6
7
ArrayOfMatrix::~ArrayOfMatrix()
{
    int i;
    for(i = 0; i < _masDimension; ++i)
            _arrayOfMatrix[i].~Matrix();
    delete[] _arrayOfMatrix;
}
А в этом случае программа вылетает "Необработанное исключение типа "System.AccessViolationException" произошло в ArrayOfMatrix.exe
Дополнительные сведения: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена."
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,135
Записей в блоге: 26
29.10.2009, 10:16     Деструктор для массива матриц... #19
Всё, увидел исходник, из-за CUT'ов что-то проморгал. Деструктор пишется симметрично с конструктором (в том плане, что delete пишется симметрично с new)

C++
1
2
3
4
5
6
void ArrayOfMatrix::Create()
{
    _arrayOfMatrix = new Matrix[_masDimension]; // <--- вот new
    for (int i = 0; i < _masDimension; ++i)
        _arrayOfMatrix[i] = Creator();  // <--- здесь никаких new нет, т.к. Creator НЕ создаёт динамических объектов
}
Правда мне не очень понятно, для чего было сделана процедура Creator. В момент выделения массива Matrix'ов для каждого элемента и так вызывается конструктор

Деструктор получается вроде бы вот такой

C++
1
2
3
4
void ArrayOfMatrix::~ArrayOfMatrix()
{
    delete[] _arrayOfMatrix;
}
Для порядку во всех конструкторах и деструкторах влепи печать, чтобы понимать сколько и чего у тебя создаётся/инициализируется
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.10.2009, 20:45     Деструктор для массива матриц...
Еще ссылки по теме:

Деструктор для дерева C++
C++ Деструктор класса. Удаление динамически выделенного массива в классе
Написать процедуру для суммирования матриц. Ошибка при передаче массива в функцию C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Vladd
0 / 0 / 0
Регистрация: 25.10.2009
Сообщений: 11
29.10.2009, 20:45  [ТС]     Деструктор для массива матриц... #20
Цитата Сообщение от Evg Посмотреть сообщение
Правда мне не очень понятно, для чего было сделана процедура Creator. В момент выделения массива Matrix'ов для каждого элемента и так вызывается конструктор
Я думал, что у меня массивы не создаются... Т.е. можно вообще оставить вот эту строчку:
_arrayOfMatrix = new Matrix[_masDimension];?
Да, кстати тут же вызывается конструктор по умлочанию, поэтому мне пришлось его сделать таким Matrix::Matrix() _rows(5), _cols(5) { Create() } А как можно избежать этой проблемы? Т.е. можно ли в строчке _arrayOfMatrix = new Matrix[_masDimension]; сделать вызов конструктора с какими-либо параметрами? Ведь по идее конструктор по умолчанию должен иметь матрицу без эл-ов...

И ещё меня волнует серьёзный вопрос.. Почему на каждую матрицу выделяется всего 12 байт??
C++
1
2
3
4
5
6
void main()
{
    ArrayOfMatrix m1(3,5,5);
    cout << &m1[0] << " " << &m1[1] << endl;
    getch();
}
Выдаёт: 003В7DC4 и 003В7DD0.. А где выделяется память на матрицу размером 5х5?? Должно же быть 25 эл-ов типа инт.. Инт = 4 байта, то как минимум надо 60 байт.. Или я ошибаюсь?

Цитата Сообщение от Evg Посмотреть сообщение
Деструктор получается вроде бы вот такой:
C++
1
2
3
4
void ArrayOfMatrix::~ArrayOfMatrix()
{
    delete[] _arrayOfMatrix;
}
Работает! Чёрт побери! Но как же всякие сложные циклы? Почему всё намного проще?
Yandex
Объявления
29.10.2009, 20:45     Деструктор для массива матриц...
Ответ Создать тему
Опции темы

Текущее время: 20:38. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru