Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.63/48: Рейтинг темы: голосов - 48, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 25.10.2009
Сообщений: 11

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

25.10.2009, 17:37. Показов 9981. Ответов 27
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Помогите написать деструктор для массива матриц.. Деструктор для матрицы вроде бы вот так пишется:
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();
}
Но компилятор ужасно злится, а потом программа вылетает..
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
25.10.2009, 17:37
Ответы с готовыми решениями:

Деструктор для массива
пишу шаблон класса: template &lt;class T&gt; class vector { T* array; public: int size;

Почему создается виртуальный деструктор A, а в таблице виртуальных функций лежит деструктор B
Почему я делаю виртуальным деструктор A, а в таблице виртуальных функций лежит деструктор B?

Глючит деструктор динамическогом массива
Деструктор: template &lt;typename TBase&gt; TArray &lt;TBase&gt;:: ~TArray ( ) { ...

27
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
25.10.2009, 17:58
Vladd, Для начала, покажи кто такой
Цитата Сообщение от Vladd Посмотреть сообщение
Matrix
0
Эксперт JavaЭксперт С++
 Аватар для M128K145
8384 / 3617 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
25.10.2009, 18:38
попробуй
так
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;
0
0 / 0 / 0
Регистрация: 25.10.2009
Сообщений: 11
26.10.2009, 19:42  [ТС]
Цитата Сообщение от 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;
}

Не спрашивайте почему я так модно создаю массив матриц Зато сам придумал
0
0 / 0 / 0
Регистрация: 25.10.2009
Сообщений: 11
27.10.2009, 16:57  [ТС]
Скажите пож-та на что вообще указывает указатель массива матриц? На элемент [0][0]?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
27.10.2009, 19:32
Ели ты про поле _arrayOfMatrix, то на _arrayOfMatrix[0], которое ты выделил через new
0
Эксперт JavaЭксперт С++
 Аватар для M128K145
8384 / 3617 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
27.10.2009, 23:12
C++
1
2
3
4
5
6
7
ArrayOfMatrix::~ArrayOfMatrix()
{
    int i;
    for(i = 0; i < _masDimension; ++i)
        _arrayOfMatrix[i].~Matrix();
    delete[] _arrayOfMatrix;
}
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
27.10.2009, 23:21
Конструктор и деструктор - это НЕ функции, а потому вызывать их нельзя
0
 Аватар для Даемоник
42 / 42 / 8
Регистрация: 22.05.2009
Сообщений: 97
27.10.2009, 23:33
Цитата Сообщение от 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.
0
Эксперт JavaЭксперт С++
 Аватар для M128K145
8384 / 3617 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
27.10.2009, 23:57
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;
}

результат
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
28.10.2009, 00:10
Я фигею... на gcc работает, на борланде работает.... Более того, на деструктор разрешается брать адрес (на конструктор - нет). Интересная штука, надо этот вопрос поизучать
0
0 / 0 / 0
Регистрация: 25.10.2009
Сообщений: 11
28.10.2009, 06:47  [ТС]
Цитата Сообщение от 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: необъявленный идентификатор
0
Эксперт JavaЭксперт С++
 Аватар для M128K145
8384 / 3617 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
28.10.2009, 07:40
Vladd, скинь код мейна
0
0 / 0 / 0
Регистрация: 25.10.2009
Сообщений: 11
28.10.2009, 08:39  [ТС]
Цитата Сообщение от 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;
}
Может есть другой метод?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
28.10.2009, 16:22
С деструктораи ситуация следующая. В стандарте действительно их можно вызывать. При этом в момент удаления объекта он всё равно будет вызван

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();
}
Code
1
2
3
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();
}
2
0 / 0 / 0
Регистрация: 25.10.2009
Сообщений: 11
28.10.2009, 19:33  [ТС]
Цитата Сообщение от 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();
}
Code
1
2
3
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... Как деструктор правильно написать?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
28.10.2009, 20:44
Ты хоть покажи всю программу целиком, а не куски-огрызки. И ткни пальцем в место, где возникает вопрос. Из прошлых объяснений я, например, не понял ничего
0
0 / 0 / 0
Регистрация: 25.10.2009
Сообщений: 11
29.10.2009, 05:15  [ТС]
Цитата Сообщение от 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
Дополнительные сведения: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена."
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
29.10.2009, 10:16
Всё, увидел исходник, из-за 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;
}
Для порядку во всех конструкторах и деструкторах влепи печать, чтобы понимать сколько и чего у тебя создаётся/инициализируется
1
0 / 0 / 0
Регистрация: 25.10.2009
Сообщений: 11
29.10.2009, 20:45  [ТС]
Цитата Сообщение от 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;
}
Работает! Чёрт побери! Но как же всякие сложные циклы? Почему всё намного проще?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
29.10.2009, 20:45
Помогаю со студенческими работами здесь

Написать процедуру для суммирования матриц. Ошибка при передаче массива в функцию
Помогите пожалуйста! Дано задание: Написать процедуру для суммирования матриц. С ее помощью сложить исходную матрицу и...

Освобождение памяти динамического массива. Деструктор
Почему выдает ошибку при написании деструктора? Если его убрать, то все работает. #pragma once #ifndef MATRIX_H #define...

Деструктор (программа, которая ищет минимальный элемент массива)
Вот написал простенькую программу, которая ищет минимальный элемент массива! С конструктором более менее разобрался, а с деструктором...

Деструктор класса. Удаление динамически выделенного массива в классе
First.h class First { private: int* num; int n; public: First(int a); ~First();

Деструктор для дерева
Добрый вечер! Помогите, пожалуйста, написать деструктор для дерева. enum color { RED, BLACK }; // Звено дерева typedef struct...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru