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

удаление динамеческого массива в деструкторе - C++

Восстановить пароль Регистрация
 
cskurt
0 / 0 / 0
Регистрация: 04.03.2013
Сообщений: 14
13.03.2013, 07:45     удаление динамеческого массива в деструкторе #1
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <iostream>
#include <time.h>
using namespace std;
class Matrix
{
public:
    int right,left,i;
    friend int operator*(Matrix &left,Matrix &right)
{
    return left*right;
}
    friend int operator+(Matrix &left,Matrix &right)
{
    return left+right;
}
    int **mass1,**mass2;
    Matrix(int n,int m)
    {
    mass1=(int **)malloc(n*sizeof(int*));
    for (i=0;i<n;i++) mass1[i]=(int*)malloc(m*sizeof(int));
    }
    Matrix()
    {
    mass2=(int**)malloc(3*sizeof(int*));
    for (i=0;i<3;i++) mass2[i]=(int*)malloc(3*sizeof(int));
    }
    ~Matrix()
    {
    }
};
int main()
{
    int i,j,n,m,k,**mass3,handle1;
    n=3; //строки
    m=3; //столбцы
    setlocale( LC_ALL,"rus" );
    srand(time(NULL)); 
    Matrix c1(n,m);
    Matrix c2;
    cout << "Матрица 1:" << endl;
    for (i=0;i<n;i++)
    {
       for (j=0;j<m;j++)
       {
           c1.mass1[i][j]=rand()%3;
           cout << c1.mass1[i][j] << " ";
       }
       cout << endl;
    }
    cout << "Матрица 2:" << endl;
    for (i=0;i<3;i++)
    {
       for (j=0;j<3;j++)
       {
           c2.mass2[i][j]=rand()%3;
           cout << c2.mass2[i][j] << " ";
       }
       cout << endl;
    }
    cout << "Перемножение матриц:" << endl;
    if (m==3)
    {
    mass3=(int**)malloc(n*sizeof(int*));
    for (i=0;i<n;i++) mass3[i]=(int*)malloc(m*sizeof(int));
    for (i=0;i<n;i++) for (j=0;j<3;j++) 
        {
    handle1=0; 
    for (k=0;k<3;k++) handle1+=c1.mass1[i][k]*c2.mass2[k][j];
    mass3[i][j]=handle1;
         }
    for (i=0;i<n;i++)
    {
       for (j=0;j<3;j++)
       {
           cout << mass3[i][j] << " ";
       }
       cout << endl;
    }
    }
    else cout << "Ошибка: Размеры матриц не соответствуют правилам умножения матриц" << endl;
    //free(mass3);
    cout << "Сложение матриц:" << endl;
    if ((n==3) && (m==3)) for (i=0;i<n;i++)
    {
       for (j=0;j<3;j++)
       {
           cout << c1.mass1[i][j]+c2.mass2[i][j] << " ";
       }
       cout << endl;
    }
    else {cout << "Ошибка: Размеры матриц не соответствуют правилам сложения матриц" << endl;}
    cout << endl;
    system("pause");
    return 0;
}
В общем что никак не могу реализовать, есть у меня тут 3 массива матриц, одна n на m, вторая 3 на 3 и третья уже выходит в соответствии с операциями. Проблема в том, что в задании мне надо деструктором очитистить память. Прописать что-то типа free() для malloc() но проблема в том что как я его там не пишу, vs 2012 ругается как только может, пробовал, может кто написать как указать его там хотя бы для одной матрицы из конструктора?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
anmartex
...
 Аватар для anmartex
1699 / 1192 / 494
Регистрация: 12.02.2013
Сообщений: 1,978
13.03.2013, 08:44     удаление динамеческого массива в деструкторе #2
cskurt, следующие моменты:
  1. Зачем вы динамически выделяете память если размерность массива заведомо известна?
  2. Почему пользуетесь malloc, а не new?
  3. Открытые паля класса нарушают инкапсуляцию.

А по части деструктора, то должно быть что-то на подобии:
C++
1
2
3
4
5
6
7
8
      ~Matrix()
      {
        for (int i = 0; i < 3; ++i)
        {
          free(mass2[i]);
        }
        free(mass2);
      }
cskurt
0 / 0 / 0
Регистрация: 04.03.2013
Сообщений: 14
13.03.2013, 11:37  [ТС]     удаление динамеческого массива в деструкторе #3
В задании: Создать класс, Матица, который будет содержать 2 конструктора. Первый будет принимать 2 параметра n и m, второй без араметров, первый конструктор будет создавать матрицу n на m, второй создавать матрицу 3 на 3. Использовать функцию malloc().

Так что такая схема реализации не моя примха, этот пример в деструкторе пробовал, работает нормально до момента нажатия клавиши, дальше вылетаем с ошибкой. Есть предположение что когда встречаем "return 0;" вызываем наш деструктор и он вот как раз и даёт сбой. Я б и не написал тут. Просто перекопал половину и-нета, для обычных функций вне деструктора у меня удаляет всё как надо, без ошибок, как прописываю в деструкторе я приплыл. Есть еще примеры? А то ошибку я ловлю по старому.
anmartex
...
 Аватар для anmartex
1699 / 1192 / 494
Регистрация: 12.02.2013
Сообщений: 1,978
13.03.2013, 12:02     удаление динамеческого массива в деструкторе #4
Цитата Сообщение от cskurt Посмотреть сообщение
Так что такая схема реализации не моя примха
Ну тогда и нужно было задание прикрепить, чтобы вопросов не возникало. А ошибки следующие:
  1. Основная: если вызвать конструктор Matrix(int n,int m), то вы выделите память под mass1mass2 останется болтаться); если вызвать конструктор по умолчанию, то болтаться останется mass2. А теперь смотрим на деструктор. В обоих случаях вы освобождаете память из под массива mass2. Улавливаете мысль?
  2. Второстепенная: если вызвать конструктор Matrix(int n,int m) с n<3, то при вызове деструктора опять схватите ошибку, а если n>3, то у вас будет утечка памяти.
cskurt
0 / 0 / 0
Регистрация: 04.03.2013
Сообщений: 14
13.03.2013, 12:23  [ТС]     удаление динамеческого массива в деструкторе #5
Не совсем, если чесно уловил мысль, в моём представлении что должно произойти (писал я в основном на ассемблере, так что и логика такая).
Код выполняется постепенно, те по мере поступления в цп, при первом вызове мы должны создать область памяти (вырезать), нам не важно где она и как, мы знаем что для доступа к ней у нас есть начальный блок и знаем сколько мы вырезали, не переходим за этот размер так как в памяти есть другие данные, если мы туда начнём лезть то обязательно что-то затрём.
Дальше мы в эту область памяти, начиная с первого указателя (начальная ячейка памяти), кидаем рандомные данные, достигнув конца нашей области мы перестаём это делать и идём дальше по коду.
Дальше идёт конструктор по умолчанию, он так же хватает область памяти (свободной) и мы туда пишем наши данные.
Потом мы их отрабатываем и удаляем эти области из системы, делая их вновь свободными.

Может я не понимаю принципа работы компилятора с++ или самой системы распределения памяти, но как если мы вызываем отдельный конструктор Matrix(int n,int m) и выделяя mass1 нас должно волновать что происходит с mass2? Да оно болтается, но оно еще и не используется. Потом вызываю по молчанию Вы написали что останется болтаться mass2, разве если я уж чего-то не понял то при первом вызове mass1 не болтался, а при втором когда мы должны были определить mass2 он у нас по прежнему болтается? Может там ошибка и болтаться у нас останется mass1? Вот что я не могу уловить, мы вызвали 2 разных конструктора, которые должны были дать нам области, как у нас может что-то после этого исчезнуть? Хотя я сейчас попробую вникнуть в ваши слова, но я скорее не понимаю принцип работы пары конструкторов и потом вызова деструктора для них обоих. На примере (самом простом) мне было бы куда яснее.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
13.03.2013, 13:51     удаление динамеческого массива в деструкторе #6
Как-то так:
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <time.h>
#include <Windows.h>
#include <iostream>
#include <cstdlib>
using namespace std;
 
class Matrix
{
public:
    int right,left,i;
    friend int operator*(Matrix &left,Matrix &right)
    {
        return left*right;
    }
    
    friend int operator+(Matrix &left,Matrix &right)
    {
        return left+right;
    }
    
    int **mass1;
    int mn, mm;
    
    Matrix(int n , int m)
    {
        mn = n; mm = m;
        mass1=(int **)malloc(n*sizeof(int*));
        for (i=0;i<n;i++) mass1[i]=(int*)malloc(m*sizeof(int));
    }
    
    Matrix()
    {
        mn = 3; mm = 3;
        mass1=(int**)malloc(3*sizeof(int*));
        for (i=0;i<mm;i++) mass1[i]=(int*)malloc(3*sizeof(int));
    }
    
    ~Matrix()
    {
        for (int i = 0; i < mn; ++i)
            free(mass1[i]);
        free(mass1);
    }
};
 
int main()
{
    setlocale( LC_ALL,"rus" );
    
    int i, j, n, m, k, **mass3, handle1;
    n = 3; //строки
    m = 3; //столбцы
    
    srand(time(NULL)); 
   
    cout << "Матрица 1:" << endl;
    
    Matrix c1(n,m);
    
    for (i=0;i<n;i++)
    {
       for (j=0;j<m;j++)
       {
           c1.mass1[i][j]=rand()%3;
           cout << c1.mass1[i][j] << " ";
       }
       cout << endl;
     }
    
    cout << "Матрица 2:" << endl;
 
    Matrix c2;
    
    for (i=0;i<3;i++)
    {
       for (j=0;j<3;j++)
       {
           c2.mass1[i][j]=rand()%3;
           cout << c2.mass1[i][j] << " ";
       }
       cout << endl;
    }
    
    cout << "Перемножение матриц:" << endl;
    if (m==3)
    {
    mass3 = (int**)malloc(n*sizeof(int*));
    for (i=0;i<n;i++) mass3[i]=(int*)malloc(m*sizeof(int));
    for (i=0;i<n;i++) for (j=0;j<3;j++) 
    {
        handle1=0; 
        for (k=0;k<3;k++) handle1+=c1.mass1[i][k]*c2.mass1[k][j];
        mass3[i][j]=handle1;
    }
    for (i=0;i<n;i++)
    {
       for (j=0;j<3;j++)
       {
           cout << mass3[i][j] << " ";
       }
       cout << endl;
    }
    }
    else cout << "Ошибка: Размеры матриц не соответствуют правилам умножения матриц" << endl;
    for (int i = 0; i < n; ++i)
            free(mass3[i]);
    free(mass3);
    
    cout << "Сложение матриц:" << endl;
    if ((n==3) && (m==3)) for (i=0;i<n;i++)
    {
       for (j=0;j<3;j++)
       {
           cout << c1.mass1[i][j]+c2.mass1[i][j] << " ";
       }
       cout << endl;
    }
    else {cout << "Ошибка: Размеры матриц не соответствуют правилам сложения матриц" << endl;}
    cout << endl;
    
    system("pause");
    return 0;
}
Добавлено через 2 минуты
Принцип, надеюсь, понятен. Матрица должна знать свой размер, поэтому в ней должны быть соответствующие поля, которые, в частности, используются при освобождении памяти.
cskurt
0 / 0 / 0
Регистрация: 04.03.2013
Сообщений: 14
13.03.2013, 13:59  [ТС]     удаление динамеческого массива в деструкторе #7
ммм, спасибо) буду сейчас разбираться) темка будет полезна многим, удаление данных для двух констркторов (задание эти данных) я нигде еще не встречал просто.
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
13.03.2013, 14:02     удаление динамеческого массива в деструкторе #8
ИМХО у автора не с деструктором проблема, а с пониманием вообще для чего нужен класс "Матрица".
Вот это что такое?
Цитата Сообщение от cskurt Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class Matrix
{
public:
* * int right,left,i;
* * friend int operator*(Matrix &left,Matrix &right)
{
* * return left*right;
}
* * friend int operator+(Matrix &left,Matrix &right)
{
* * return left+right;
}
* * int **mass1,**mass2;
почему класс "матрица" содержит ДВЕ матрицы? Класс Матрица Это пользовательский ТИП ДАННЫХ! Он должен описывать одну переменную данного типа - одну матрицу.
Короче... Автор, найди в инете пример класса Матрица или Вектор или вообще какого либо класса
и изучай до посинения.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
13.03.2013, 14:08     удаление динамеческого массива в деструкторе #9
И зачем создавать вручную третью матрицу если есть класс? Что-то так (код не додумываю, просто для размышлений):
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
Matrix c3;
    if (c3.mn == 3)
        {
        for (i = 0; i < n; i++) for (j = 0; j < 3; j++) 
        {
            handle1=0; 
            for (k = 0;k < 3; k++) handle1+=c1.mass1[i][k] * c2.mass1[k][j];
            c3.mass1[i][j]=handle1;
        }
    
        for (i=0;i<n;i++)
        {
           for (j=0;j<3;j++)
           {
               cout << c3.mass1[i][j] << " ";
           }
           cout << endl;
        }
    
    } else cout << "Ошибка: Размеры матриц не соответствуют правилам умножения матриц" << endl;
    
    /*for (int i = 0; i < n; ++i)
            free(mass3[i]);
    free(mass3);*/,
cskurt
0 / 0 / 0
Регистрация: 04.03.2013
Сообщений: 14
13.03.2013, 14:09  [ТС]     удаление динамеческого массива в деструкторе #10
Я за 4-ре дня на с++ дошел уже до этого, раньше был лишь ассемблер, поэтому пробелов много, их просто тьма и да, мне на примере было больше понятно что происходит, теория она содержит кучу того что тебе сейчас не надо (даже непонятно), а конкретный пример явно показывает что надо сделать.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
13.03.2013, 14:18     удаление динамеческого массива в деструкторе #11
И вот это:
Цитата Сообщение от anmartex Посмотреть сообщение
Открытые паля класса нарушают инкапсуляцию.
И тогда предусмотреть методы для извлечения полей матрицы.

Добавлено через 7 минут
Цитата Сообщение от cskurt Посмотреть сообщение
удаление данных для двух констркторов
Тут дело не в двух конструкторах, а в том, что у вас в одном объекте класса две матрицы, которые, к тому же, инициализируются разными конструкторами. Должно быть: один объект - одна матрица, которая знает свой размер, и тогда не важно сколько конструкторов.
cskurt
0 / 0 / 0
Регистрация: 04.03.2013
Сообщений: 14
13.03.2013, 15:01  [ТС]     удаление динамеческого массива в деструкторе #12
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cout << "Перемножение матриц:" << endl;
    if (m==3)
    {
    Matrix c3(n,3);
    for (i=0;i<n;i++) for (j=0;j<3;j++) 
    {
        handle1=0; 
        for (k=0;k<3;k++) handle1+=c1.mass1[i][k]*c2.mass1[k][j];
        c3.mass1[i][j]=handle1;
    }
    for (i=0;i<n;i++)
    {
       for (j=0;j<3;j++)
       {
           cout << c3.mass1[i][j] << " ";
       }
       cout << endl;
    }
    }
    else cout << "Ошибка: Размеры матриц не соответствуют правилам умножения матриц" << endl;
я как увидел реализацию констрктора и дестрктора для матриц сразу догадался как правильнее будет сделать, всем спасибо, без вас я бы еще неделю долбился бы.

Добавлено через 42 минуты
Ну и под конец инкапсуляция если правильно понял что это и реализовал вот код, если это не инкапсуляция скажите, я попробую сам переписать. Если же всё верно, пригодится, думаю, другим в понимании разницы. Код.

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <time.h>
#include <iostream>
using namespace std;
 
class Matrix
{
private:
    int mn,mm,**mass1;
    int right,left,i;
public:
    friend int operator*(Matrix &left,Matrix &right)
    {
        return left*right;
    }
    
    friend int operator+(Matrix &left,Matrix &right)
    {
        return left+right;
    }
    
    
    Matrix(int n,int m)
    {
        mn=n;mm=m;
        mass1=(int**)malloc(n*sizeof(int*));
        for (i=0;i<n;i++) mass1[i]=(int*)malloc(m*sizeof(int));
    }
    
    Matrix()
    {
        mn=3;mm=3;
        mass1=(int**)malloc(3*sizeof(int*));
        for (i=0;i<mm;i++) mass1[i]=(int*)malloc(3*sizeof(int));
    }
    
    ~Matrix()
    {
        for (int i=0;i<mn;++i)
            free(mass1[i]);
        free(mass1);
    }
    int get(int i,int j)
    {
        return mass1[i][j];
    }
    void set(int i,int j)
    {
        mass1[i][j]=rand()%3;
    }
    void set(int i,int j,int handle1)
    {
        mass1[i][j]=handle1;
    }
 
};
 
int main()
{
    setlocale( LC_ALL,"rus" );
    
    int i,j,n,m,k,handle1;
    n=3; //строки
    m=3; //столбцы
    
    srand(time(NULL)); 
   
    cout << "Матрица 1:" << endl;
    
    Matrix c1(n,m);
    
    for (i=0;i<n;i++)
    {
       for (j=0;j<m;j++)
       {
           c1.set(i,j);
           cout << c1.get(i,j) << " ";
       }
       cout << endl;
     }
    
    cout << "Матрица 2:" << endl;
 
    Matrix c2;
    
    for (i=0;i<3;i++)
    {
       for (j=0;j<3;j++)
       {
           c2.set(i,j);
           cout << c2.get(i,j) << " ";
       }
       cout << endl;
    }
    
    cout << "Перемножение матриц:" << endl;
 if (m==3)
 {
 Matrix c3(n,3);
 for (i=0;i<n;i++) for (j=0;j<3;j++) 
 {
 handle1=0; 
 for (k=0;k<3;k++) handle1+=c1.get(i,k)*c2.get(k,j);
 c3.set(i,j,handle1);
 }
 for (i=0;i<n;i++)
 {
 for (j=0;j<3;j++)
 {
 cout << c3.get(i,j) << " ";
 }
 cout << endl;
 }
 }
 else cout << "Ошибка: Размеры матриц не соответствуют правилам умножения матриц" << endl;
    
    cout << "Сложение матриц:" << endl;
    if ((n==3) && (m==3)) for (i=0;i<n;i++)
    {
       for (j=0;j<3;j++)
       {
           cout << c1.get(i,j)+c2.get(i,j) << " ";
       }
       cout << endl;
    }
    else {cout << "Ошибка: Размеры матриц не соответствуют правилам сложения матриц" << endl;}
    cout << endl;
    
    system("pause");
    return 0;
}
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
13.03.2013, 15:10     удаление динамеческого массива в деструкторе #13
Это что за поля?
C++
1
int right,left,i;
cskurt
0 / 0 / 0
Регистрация: 04.03.2013
Сообщений: 14
13.03.2013, 15:40  [ТС]     удаление динамеческого массива в деструкторе #14
Это, я выделил блоки памяти под хранение перегрузки операторов * и +, по сути там должен быть обработчик ошибок(насколько я понял задание) но оно пока обрабатывается в мейн функции без возврата значений.

Я прикрепил там картинку с фоткой задания, думаю там обработку на возможность умножения и сложения матриц надо сделать в операторах перегрузки, пока лишь я сделал это примитивно, так как еще решение не посетило, обрабатывать входящие данные (по какому признаку ведь в значениях NULL будет). И я правильно понял, что подобным мы выделяем ячейки памяти где потом будут храниться данные которые поступают на перегруженные операторы?
 Комментарий модератора 
Текст задания перепечатайте в тему
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.03.2013, 16:28     удаление динамеческого массива в деструкторе
Еще ссылки по теме:

C++ Классы - ошибка в деструкторе
Оператор delete в деструкторе C++
C++ Ошибка в деструкторе

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

Или воспользуйтесь поиском по форуму:
cskurt
0 / 0 / 0
Регистрация: 04.03.2013
Сообщений: 14
13.03.2013, 16:28  [ТС]     удаление динамеческого массива в деструкторе #15
Создать класс, матрица, который содержит 2 конструктора. Один с параметрами m,n, второй без параметров. Первый конструктор создаёт матрицу m*n, второй 3*3.(используя функцию malloc). Определить как friend operator * если умножение невозможно сообщить об ошибке. operator + сложение матриц, деструктор очищает память.
Yandex
Объявления
13.03.2013, 16:28     удаление динамеческого массива в деструкторе
Ответ Создать тему
Опции темы

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