Operator 'delete' applied to 'new' created variables needed as return of a function

Greetings,

I'm doing some matrices operations and I need to dinamically create 2-D arrays inside my funcions. I create the arrays with the 'new' operator. How can I use 'delete' operator to free the memory if I need the variable to return as the result of the function? The code presented was developed under DevCPP/Windows.

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
#include <iostream>
using namespace std;

float ** multiply(float **A,int lA,int cA,float **B,int lB,int cB) {
    int i,j,k;
    float acc;
    // Creating result R as a dinamic 2-D array
    float **R = new float*[lA];
    for(i=0;i<lA;i++) R[i] = new float[cB];
    // Check if operation is possible and, if so, perfom it
    if(cA == lB) {
        for(i=0;i<lA;i++)
            for(j=0;j<cB;j++){
                acc = 0;
                for(k=0;k<cA;k++) acc += A[i][k]*B[k][j];
		R[i][j] = acc;
            }
    } else perror("Matrix A must have same number of columns than number of lines of matrix B");
    return R;
}

float ** transpose(float **A,int lA,int cA) {
    int i,j;
    // Creating result T as a dinamic 2-D array
    float **T = new float*[cA];
    for(i=0;i<cA;i++) T[i] = new float[lA];
    // Perfom it
    for(j=0;j<cA;j++)
        for(i=0;i<lA;i++)
            T[j][i] =A[i][j];
    return T;
}

int main(int argc, char* argv[]){
    int i,j,N=3,M=5;
    float ** Y;
    // Initialize X
    float ** X = new float *[N];
    for(i=0;i<N;i++) X[i] = new float[M];
    for(i=0;i<N;i++)
        for(j=0;j<M;j++)
            if (i == j) X[i][j] = i*j; else X[i][j] = i+j;
    // Print array X
    for(i=0;i<N;i++) {
        for(j=0;j<M;j++) cout << X[i][j] << " ";
        cout << endl;
    }
    cout << endl;
    // Calculate Y
    Y = multiply(X,N,M,transpose(X,N,M),M,N);
    // Print array Y
    for(i=0;i<N;i++) {
        for(j=0;j<N;j++) cout << Y[i][j] << " ";
        cout << endl;
    }
    cout << endl;
    // Free memory (?)
    for(i=0;i<3;i++) delete [] X[i];
    delete [] *X;
    for(i=0;i<3;i++) delete [] Y[i];
    delete [] *Y;
    // End of program
    system("pause");
    return 0;
}


This code dinamically generates 3 basic 2-D arrays: R (multiply, NxN); T (transpose, MxN); and X (matrix-argument, MxN). Y will receive R. When the code "frees" the memory before end of program, it will free the Y(=R) array (NxN) and the X array (NxM). How can I free the T array (MxN)? I cannot delete it before return, neither after!

Does anybody knows about it? I should be thankful for any help on this.
You lost the pointer because you didn't keep a copy of it.
1
2
3
float **T=transpose(X,N,M);
Y = multiply(X,N,M,T,M,N);
//free T 

One suggestion: encapsulate inside a class. It will really clean up your code in main(), while at the same time preventing this situation from accidentally arising again.
Hi helios

Memory concern is a new worry for me. The code I posted above is just an example. There are situations when I use recursive functions with this kind of problem (e.g. matrix inversion)... A dumb example follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int * foo(int * x, int T, size_t N){
    if (N > 1) {
        int * y = new int [N];
        size_t i;
        int acc = 0;
        for (i = 0; i < N; i++) acc += x[i];
        if (acc < T) for  (i = 0; i < N; i++) y[i] = x[i];
        else y = foo(x, T, N-1);
    }
    else {
        int * y = new int [1];
        y[0] = x[0];
    }
    return y;
}


How do I keep track of all dynamic allocated memory in each recursion step to future deallocation? Is it possible? If the way you posted is the only way, I'll need to reformulate all the way I see recursive functions.

What about the encapsulation suggestion? When the class instance is destroyed, all dynamic allocated memory through its members are deallocated? If it is so, this is great news!

By the way, just a curiosity: how do I keep track of heap memory in C++? I mean, how can I keep track of dynamic allocated memory that is not free yet? Is there some ANSI/ISO function that can return the amount of heap or stack memory still available?
Last edited on

By the way, just a curiosity: how do I keep track of heap memory in C++? I mean, how can I keep track of dynamic allocated memory that is not free yet? Is there some ANSI/ISO function that can return the amount of heap or stack memory still available?


You can use smart pointers (e.g. from Boost), but beware they add quite a lot of overhead - e.g. every pointer creation or copying adds several CPU cycles, including branches, which are quite costly. If you use them too often, e.g. for all the pointers in your program (a bad idea), you can expect your programs to be several times slower than the Java/C# equivalents using proper GC.


(e.g. matrix inversion)


Why ever need to code matrix inversion? Matrix inversion algorithms are numerically unstable, it is much better to redesign the algorithm in such a way to avoid matrix inversion completely.
Last edited on
Sorry, rapidcoder

I think I'm not making myself clear. Somehow, I need to keep track of dynamical allocated memory addresses when I'm doing a recursive function, in order to deallocate them after use (as helios kindly pointed out). At this point, I'm not concerned on what I'm doing, I'm trying to undersatnd an issue to change the way I've been programming.

Could somebody tell me if the following strategy is valid (vector of void*)? I mean, the code is running, but I can't tell if the memory is beeing correctly deallocated or not.

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
#include <iostream>
#include <vector>
using namespace std;

vector<void *> dynmem;
vector<void *>::iterator idm;

struct myclass {
  myclass() {cout <<"myclass constructed\n";}
  ~myclass() {cout <<"myclass destroyed\n";}
};

myclass ** dosomething(int N) {
    cout << "in" << endl;
    myclass ** xx = new myclass*[N];
    dynmem.push_back(xx);
    for (int i = 0; i < N; i++) {
        xx[i] = new myclass[N]; 
        dynmem.push_back(xx[i]);
    }
    cout << "out" << endl;
    return xx;
}

int main () {
  int N = 2;
  myclass ** xx;// = new myclass[N];
  xx = dosomething(N);
  for (idm = dynmem.end(); idm >= dynmem.begin(); idm--) delete [] (*idm);
  // If I use the following lines instead of the line above, 'myclass' prints out it is destroyed
  //for (int i = 0; i < N; i++) delete xx[i];
  //delete [] *xx;
  system("pause");
  return 0;
}


If could anybody also get me some code to get runtime memory informstion (heap and swap), I would appreciate it very much.
1
2
3
4
for(i=0;i<3;i++) delete [] X[i];
    delete [] *X;
    for(i=0;i<3;i++) delete [] Y[i];
    delete [] *Y;

you could just write like this
delete []X;
delete []Y;
even if X point to a 100-D array, you could just use delete []X;
this is because C and C++ has no built-in multi-dimention arrays, they only support one-dimension array. All multi-dimension arrays are simulated by the basic one-dimension array.
If you don't want to worry about the dynamically allocated resource, use smart pointers. This technique is call RAIIResource Aquisition Is Initialization). You could just google "RAII" or "auto_ptr".
Good Luck:)
closed account (D80DSL3A)
@iperetta. Using a vector to store the pointers seems like a decent approach (if you aren't going to create a wrapper class to manage memory use automatically).
Your method seems too complicated though. For example, why store myclass** as the 1st element when you are storing all of the pointers it points to?

Compare to this method. Hopefully I haven't missed the point of what you're doing.
Also, forgive my laziness, I substituted M for myclass in the following code:
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
#include <iostream>
#include <vector>
using namespace std;

class M
{
    public:
    int x;
    M():x(0){cout << "M const  ";}
    ~M(){cout << "M destr  ";}
};

// passing vector by reference to avoid creating a copy of it
void alloc( vector<M*>& v_pM, int R, int C )
{
    for(int r=0; r<R; ++r)
    {
        v_pM.push_back( new M[C] );
        cout << endl;
    }
}

void release( vector<M*>& v_pM )
{
    for(vector<M*>::iterator it = v_pM.begin(); it != v_pM.end(); ++it)
    {
        delete [] *it;
        cout << endl;
    }
}

int main()
{
    vector<M*> pMvec;// store pointers to each row of Ms

    cout << "Allocating 2D array of Ms:" << endl;
    alloc( pMvec,3,4 );// 3 rows (lines) by 4 columns
    cout << endl;

    cout << "Deleting 2D array of Ms:" << endl;
    release( pMvec );

    cout << endl;
    return 0;
}// end of main() 


Output:

Allocating 2D array of Ms:
M const  M const  M const  M const
M const  M const  M const  M const
M const  M const  M const  M const

Deleting 2D array of Ms:
M destr  M destr  M destr  M destr
M destr  M destr  M destr  M destr
M destr  M destr  M destr  M destr

The output indicates that the appropriate number of allocations and deletions were made.

Notice that I used a vector<M*> that is local to main() instead of global.
This gives the advantage that the alloc() and release() functions are not written to work with a specific vector. You could use the functions to create several 2D arrays by supplying different vectors to store each arrays pointers in.

EDIT:
Why not write alloc() and release() as template functions so they can work with arrays of any class type?

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
#include <iostream>
#include <vector>
using namespace std;

class A
{
    public:
    int x;
    A():x(0){cout << "A const  ";}
    ~A(){cout << "A destr  ";}
};

class B
{
    public:
    float f;
    char c;
    B():f(0.0f), c('B'){cout << "B const  ";}
    ~B(){cout << "B destr  ";}
};

template<class T>
void alloc( vector<T*>& v_pT, int R, int C )
{
    for(int r=0; r<R; ++r)
    {
        v_pT.push_back( new T[C] );
        cout << endl;
    }
}

template<class T>
void release( vector<T*>& v_pT )
{
    for(typename std::vector<T*>::iterator it = v_pT.begin(); it != v_pT.end(); ++it)
    {
        delete [] *it;
        cout << endl;
    }
}

int main()
{
    vector<A*> pAvec;// store pointers to each row of As
    cout << "Allocating 2D array of As:" << endl;
    alloc( pAvec,3,4 );// 3 rows (lines) by 4 columns
    cout << endl;

    vector<B*> pBvec;// for array of B objects
    cout << "Allocating 2D array of Bs:" << endl;
    alloc( pBvec,2,5 );// 2 rows (lines) by 5 columns
    cout << endl;

    cout << "Deleting 2D array of As:" << endl;
    release( pAvec );
    cout << endl;

    cout << "Deleting 2D array of Bs:" << endl;
    release( pBvec );

    cout << endl;
    return 0;
}// end of main() 


Output:

Allocating 2D array of As:
A const  A const  A const  A const
A const  A const  A const  A const
A const  A const  A const  A const

Allocating 2D array of Bs:
B const  B const  B const  B const  B const
B const  B const  B const  B const  B const

Deleting 2D array of As:
A destr  A destr  A destr  A destr
A destr  A destr  A destr  A destr
A destr  A destr  A destr  A destr

Deleting 2D array of Bs:
B destr  B destr  B destr  B destr  B destr
B destr  B destr  B destr  B destr  B destr
Last edited on
Thank you, guys!
Topic archived. No new replies allowed.