[c++] a problem with memory...

i'm writing in c++ a class to manage matrixs.

matrici.h
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
#include <cstdlib>
#include <iostream>

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#ifndef _MATRICI_H
#define _MATRICI_H 1

//**************** class ******************//

class matrice {
    public:
        int r;
        int c;
        double ** m;
        
        //costruttore e distruttore
        matrice();
        ~matrice();
        
        //crea matrice
        void create(int r, int c);
        void create_with_value(int r, int c, double value);
        
        //visualizza matrice
        void print();
        
        //caricamento - salvataggio matrici
        void load_from_file(char * file);
        void save_in_file(char * file);
        
        //operazioni su matrici
        friend matrice operator+(matrice, matrice);
        
        
};
    
#endif 


matrici.cpp
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
131
132
133
134
135
136
137
138
139
140
141
142
143
#include "matrici.h"

//costruttore
matrice::matrice(){
    r = 0;
    c = 0;    
}

//distruttore
matrice::~matrice(){
    
}

//creazione matrice
void matrice::create(int r, int c){ // r = righe, c = colonne

    int x,y;
     
    this->r = r;
    this->c = c;
    m = new double *[r];
    for(x=0;x<r;x++)
        m[x] = new double[c];

         
}
void matrice::create_with_value(int r, int c, double value){
    
    int x,y;
     
    this->r = r;
    this->c = c;
    m = new double *[r];
    for(x=0;x<r;x++)
        m[x] = new double[c];
            
    for(x=0;x<r;x++)
        for(x=0;x<r;x++)
            m[x][y] = value;
     
}

//visualizza matrice
void matrice::print(){
     
     int x,y;
     
     for(x=0;x<r;x++){
          for(y=0;y<c;y++)
               printf("%12.6f\x20",m[x][y]);
          printf("\n");     
     }
     printf("\n");
     
}

//caricamento - salvataggio matrici
void matrice::load_from_file(char * file){
    
    FILE *stream;
    char *buffer, *number;
    long filesize, readed;
    long x, y=0, mr=0, mc=0, r=0, c=0;

    stream = fopen(file,"rb");
    fseek(stream,0,SEEK_END);
    filesize = ftell(stream);
    rewind(stream);
    
    buffer = (char *) malloc(filesize * sizeof(char));
    number = (char *) malloc(100 * sizeof(char));
    readed = fread(buffer,1,filesize,stream);
    
    for(x=0; x<filesize ;x++){ //conta colonne
        if(buffer[x] == '\x09')
            mc++;
        if(buffer[x] == '\x0D'){
            mc++;
            break;
        }
    }
    for(x=0; x<filesize ;x++){ //conta righe
        if(buffer[x] == '\x0D')
            mr++;
    }
    
    create(mr, mc);
    
    for(x=0; x<filesize ;x++){
        if(buffer[x] == '\x0A')
            continue;
        if(buffer[x] == '\x09' || buffer[x] == '\x0D'){
            number[y] = '\x00';
            this->m[r][c] = atof(number);
            y=0;
            c++;
            if(buffer[x] == '\x0D'){
                r++;
                c=0;
            }
        }
        else{
            number[y] = buffer[x];
            y++;
        }
    }

}

void matrice::save_in_file(char * file){

    int x,y;
    FILE * stream;
    stream = fopen(file, "w+");
    
    for(x=0;x<r;x++){
        for(y=0;y<c;y++){
            fprintf(stream,"%.6f",m[x][y]);
            if(y<c-1) fprintf(stream,"\x09");
        }
        fprintf(stream,"\n");     
    }
    fclose(stream);

}

//operazioni su matrici
matrice operator+(matrice a,matrice b){
    
    matrice c;
    int x,y,i;
     
    if(a.r != b.r || a.c != b.c)
        exit(0);
     
    c.create(a.r, a.c);
     
     for(x=0;x<c.r;x++)
          for(y=0;y<c.c;y++)
               c.m[x][y] = a.m[x][y]+b.m[x][y];   

    return c;
}



we can try this class with this code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "matrici.h"


int main(int argc, char *argv[])
{
    long x;

    matrice a,b;
    a.load_from_file("a.txt");
    a.save_in_file("b.txt");

    a.print();

    for(x=0;x<1000000000;x++)
        b = a + a;
    
    b.print();

    getchar();
    return 1;
}

this example shows very well the problem: doing 1000000000 times b=a+a; the memory used by the program increases a lot... i should find a way to free memory when i do not need it anymore.
but i don't know how to do it...

thank you very much,
Marco
Last edited on
delete stuff in your destructor.
1
2
3
4
 
for(x=0;x<r;x++)
     delete[] m[x];
delete[] m;

ok, i added delete stuff in my destructor
1
2
3
4
5
6
7
8
matrice::~matrice(){
    
    int x;
    for(x=0;x<r;x++)
        delete[] m[x];
    delete[] m;
    
}


now there is a new problem...
i try this code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "matrici.h"


int main(int argc, char *argv[])
{
    long x;

    matrice a,b;
    a.load_from_file("a.txt");
    a.save_in_file("b.txt");

    a.print();

    for(x=0;x<100000;x++)
    b = a + a;

    
    b.print();

    getchar();
    return 1;
}

and at runtime it give error...
because your code in the destructor after the operation b=a+a destroy all the arrays before the new loop, so it erase all the memory, also the one that i need...
Last edited on
I see the problem
You don't define a copy constructor and an assignment operator. So multiple objects use the same memory block.
Define
 
matrice::matrice(const matrice& o);

and
 
matrice& matrice::operator=(const matrice& o);

Both of them should make a copy of the contents of o.m and copy them to this->m.

EDIT: also operator+ should take it's arguments by const references not by value. See the above function declarations for const references.
Last edited on
ok... for matrice& operator=(const matrice& o); i tried in this way

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
friend matrice operator=(matrice a);

matrice operator=(matrice a){
    
    int x,y;
    matrice b;
    
    b.create(a.r,a.c);
    
    for(x=0;x<a.r;x++)
          for(y=0;y<a.c;y++)
               b.m[x][y] = a.m[x][y];
               
    return b;
}


but my compiler (dev-c++) gives me theese errors...
1
2
3
4
42 D:\Marco\MyProjects\matematica\classe matrici\matrici.h `matrice operator=(matrice)' must be a nonstatic member function 
42 D:\Marco\MyProjects\matematica\classe matrici\matrici.h `matrice operator=(matrice)' must take exactly two arguments 
136 D:\Marco\MyProjects\matematica\classe matrici\matrici.cpp `matrice operator=(matrice)' must be a nonstatic member function 
136 D:\Marco\MyProjects\matematica\classe matrici\matrici.cpp `matrice operator=(matrice)' must take exactly two arguments 



and I do not understand what do you mean with matrice(const matrice& o);

sorry, it's just few days that i'm trying c++ (i usually use c) and so i not very good.

thanks a lot for your help ;)
Last edited on
Copy constructor should look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// in h file
class matrice {
//...
matrice(const matrice& o);
//...
}

//in cpp file:
matrice::matrice(const matrice& o) {
   
    create(o.r,o.c);
    for(int x=0;x<r;x++)
        for(int y=0;y<c;y++)
            m[x][y] = o.m[x][y];
}


Assigment operator shoudl look like this:
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
// in h file
class matrice {
//...
matrice& operator=(const matrice& o);
//...
}

//in cpp file:
matrice& matrice::operator=(const matrice& o) {

    if (this == &o) { //We don't wanna copy ourselves into ourselves.
        return *this; //EDIT : added "*this"
    } 
    //deallocate current stuff
    for(x=0;x<r;x++)
        delete[] m[x];
    delete[] m;
    
    //allocate memory for new matrix, and copy the contents. 
    create(o.r,o.c);
    for(int x=0;x<r;x++)
        for(int y=0;y<c;y++)
            m[x][y] = o.m[x][y];

    return *this;
}


I haven't tested the code due to the lack of complier on this computer, so there could be syntax and other errors.


I hope you can use this example in the future on other classes you desing :)

Take care
Last edited on
wow... now it works perfectly...
thank you very much for helping me!!

of course i will use your example when i will need it again, and now I study to understand all the things you taught me. :)

Marco
Last edited on
Topic archived. No new replies allowed.