How to deallocate an array

How can i make sure I delete my array, my destructor is not being called and now i have memory leak.

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

int main()
{
	cout << " Enter the size of the array : ";
	int size_arr;
	cin >> size_arr;

	Array arr(size_arr);

	system("pause");
	return 0;
}

#include <iostream>
#include <string>
#include "Arr.h"

using namespace std;

Arr::Arr() {

	size = 0;
	pArr = NULL;
	
	cout << " Default constructor called" << endl;
}



Arr::Arr(int arr_size) { //int is to receive an array size

	size = arr_size;
	if (size == 0) {
		create_arry();
	}
	else {
		pArr = new double[size];
	}
	// array size should be set here, this is what main is going to call 
	cout << "Overloaded constructor called " << endl;
} 

Arr::~Arr() {

	cout << "Destructor is Called " << endl;
	delete[] pArr;
}

void Array::create_arry() {

	pArr = new double[6];
}
How can i make sure I delete my array, my destructor is not being called and now i have memory leak.
1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
	cout << " Enter the size of the array : ";
	int size_arr;
	cin >> size_arr;
     {
	Array arr(size_arr);
     } //force scope 

	system("pause"); //otherwise this happens
	return 0;
} //before destructor is called down here... 
Last edited on
What is telling you that you have a memory leak? Is there more code beside this?

What would you be deleting if the object had been created with the default constructor?

Have you defined a copy constructor and copy assignment as well?
What do you mean by forcing a scope? Is that a regular solution, or is that a last resort solution? @Jonnin I dont think planting brackets just like that is a very good idea...
@Last chance, we are not doing copy constructors just yet, they are not part of this project. I have no worked on the other functions but they do not matter as of right now, because all they do is manipulate the data of the array like reversing, etc.
I know there is memory leak because i am allocating memory in the heap by using new, and my destructor is not being called
@rnima

Using what you have so far:
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
#include <iostream>

class Arr
{
private:
    int size{0};
    double* pArr = nullptr;
    
public:
    Arr() { std::cout << " Default constructor called" << '\n'; }
    
    Arr(int arr_size)
    {
        if(size > 0)
        {
            size = arr_size;
            pArr = new double[size];
        }
        std::cout << "Overloaded constructor called\n";
    }
    
    ~Arr()
    {
        if(size > 0)
            delete [] pArr;
        
        std::cout << "Destructor called\n";
    }
};

int main()
{
    std::cout << " Enter the size of the array: ";
    int size_arr;
    std::cin >> size_arr;
    
    Arr arr(size_arr);
    return 0;
}


Enter the size of the array: 0
Overloaded constructor called
Destructor called
Program ended with exit code: 0


Enter the size of the array: 203
Overloaded constructor called
Destructor called
Program ended with exit code: 0
And
1
2
3
4
5
6
7
8
9
10
11
int main()
{
    std::cout << " Enter the size of the array: ";
    int size_arr;
    std::cin >> size_arr;
    
    Arr arr(size_arr);
    
    Arr brr;
    return 0;
}


Enter the size of the array: 2
Overloaded constructor called
 Default constructor called
Destructor called
Destructor called
Program ended with exit code: 0
@rnima

There is little point in posting your code when it isn't that code that is causing the problem.

Apparently your class is called "Array" in main and "Arr" everywhere else.

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

class Arr
{
   int size;
   double *pArr;

public:
   Arr( int arr_size )
   {
      size = arr_size;
      if ( size == 0 )
      {
         create_arry();
      }
      else
      {
         pArr = new double[size];
      }
      cout << "Constructor called with size " << size << '\n';
   }

   ~Arr()
   {
      cout << "Destructor is called\n";
      delete[] pArr;
   }

   void create_arry()
   {
      size = 6;
      pArr = new double[size];
   }
};

int main()
{
   cout << "Enter the size of the array: ";
   int size_arr;
   cin >> size_arr;

   Arr arr(size_arr);
}


Enter the size of the array: 10
Constructor called with size 10
Destructor is Called



rnima wrote:
I know there is memory leak because i am allocating memory in the heap by using new, and my destructor is not being called

Then you know wrong.



rnima wrote:
I dont think planting brackets just like that is a very good idea...

I think it is an excellent idea. When it gets to the end of that limited scope, anything created within that scope will end its lifetime and have its destructor called.
Last edited on
Another permutation:

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
#include <iostream>

class Arr
{
private:
    int size{0};
    double* pArr = nullptr;
    
public:
    Arr() { std::cout << " Default constructor called" << '\n'; }
    
    Arr(int arr_size)
    {
        create_array(arr_size);
        std::cout << "Overloaded constructor called\n";
    }
    
    ~Arr()
    {
        if(size > 0)
        {
            delete [] pArr;
            std::cout << "pArr deleted\n";
        }
        
        std::cout << "Destructor called\n";
    }
    
    void create_array(int arr_size)
    {
        if(arr_size > 0)
        {
            size = arr_size;
            pArr = new double[size];
        }
    }
};

int main()
{
    std::cout << " Enter the size of the array: ";
    int size_arr;
    std::cin >> size_arr;
    
    Arr arr(size_arr);
    
    Arr brr;
    Arr crr;
    crr.create_array(99);
    
    return 0;
}



Enter the size of the array: 9
Overloaded constructor called
 Default constructor called
 Default constructor called
pArr deleted
Destructor called
Destructor called
pArr deleted
Destructor called
Program ended with exit code: 0
Last edited on
I dont think planting brackets just like that is a very good idea..

I said why in the comments.
The brackets show that your destructor is working; they are not useful in a real program. You are not totally wrong here, but it shows you what you needed to see with the least amount of surgery. You should take them back out once you see what you need to see with them in.



What I am seeing is you not run the program from a console window, and instead relying on system pause from the gui. This is ok but you can't see the destructor being called this way because it is called after the pause ended. It is working fine, you just can't see it because of how you choose to run your program.

Last edited on
Introducing scope in the middle of a function as above is extremely useful and it's something I personally do frequently. It's a great way to ensure an object will be destructed at a specific point without having to introduce a new function and pass everything I need to it. The simplest example I can think of is
1
2
3
4
5
6
7
Foo foo;
foo.before_bar();
{
    auto lock = bar.lock(); //std::unique_lock<std::mutex>
    bar.critical(foo);
}
foo.quux();

Besides locks, there's other objects where order of destruction may be critical, such as streams, network connections, database connections, and global system objects.
Last edited on
This is true. I rarely need these, and misspoke as to its usefulness.
Topic archived. No new replies allowed.