Problem with delete []

Hi,
I am a beginner in c++ and to this forum. I am trying to write a code for defining a 3-d array and some simple operations on it. However, my code seems to have some issue related to using delete [].
The idea is to define a 1-d array and define the indexing in such a way that we can use it as a 3-d array. I also want to define a term-wise summation for two such arrays by overloading operator +. Now, my operator seems to work fine but there is a runtime error during execution. I have given the code and output error below. Can somebody please point out what is happening here and how can I fix it?

Thank in advance.

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
class array3d {
	
	public:
	int n1, n2, n3;
	long double * array;
		
	//constructors
	array3d () {};
	array3d (int u, int v, int x);
	//destructor
	~array3d ();
	
	//operator overload
	//indexing
	long double& operator () (int x, int y, int w);
	//other matrix operations
          array3d operator + (array3d);
};

////constructor 1
array3d::array3d (int u, int v, int x)
{
	n1 = u;
	n2 = v;
	n3 = x;
	if(n1>0 && n2>0 && n3>0)
	{
		array = new long double [n1*n2*n3];
	}
}

//destructor
array3d::~array3d()
{
	delete[] array;
}

//indexing
long double& array3d::operator () (int x, int y, int w)
{
	return array[x + n1*y + n1*n2*w];
}

//summation
array3d array3d::operator + (array3d mat)
{
	int i;
	array3d temp(n1, n2, n3);
	if(n1>0 && n2>0 && n3>0)
	{
		for(i=0; i<n1*n2*n3; i++)
		{
			temp.array[i] = array[i] + mat.array[i];
		}
	}
	return temp;
} 

//main
int main()
{
	array3d mat1(2, 2, 2), mat2(2, 2, 2), mat3;
	
	for(int i=0; i<2; i++)
	{
		for(int j=0; j<2; j++)
		{
			for(int k=0; k<2; k++)
			{
				mat1(i,j,k) = i+10*j+100*k;
				mat2(i,j,k) = (i+10*j+100*k)*100;
			}
		}
	}
	
	mat3 = (mat1 + mat2);
	
	cout << "printing mat3" << "\n";

	for(int i=0; i<2; i++)
	{
		for(int j=0; j<2; j++)
		{
			for(int k=0; k<2; k++)
			{
				cout << mat3(k,j,i) << "\n";
			}
		}
	}

	return 0;
}



printing mat3
0
101
1010
1111
10100
10201
11110
11211
*** glibc detected *** ./a.out: double free or corruption (top): 0x084fb070 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0x37bee2]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdlPv+0x1f)[0x21651f]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdaPv+0x1b)[0x21657b]
./a.out[0x8048779]
./a.out[0x8048c0b]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x31f4d3]
./a.out[0x8048641]
======= Memory map: ========
.....
.....
.....
b7731000-b7734000 rw-p 00000000 00:00 0 
b774b000-b774f000 rw-p 00000000 00:00 0 
bf8dc000-bf8fd000 rw-p 00000000 00:00 0          [stack]
Aborted (core dumped)
array3d array3d::operator + (array3d mat)

Try passing the class as reference
array3d array3d::operator + (array3d& mat)

because I had same kind of issue. I passed my class vector (where delete function was there for array) as value. So in the main after the program executes, it couldnt delete the array and threw me the core dump error

Sorry for the wrong guidance. No need of destructor, because it is needed only when u create an array dynamically using pointer.
so take out that destructor and you didnt implement the default constructor.
Last edited on
Thank you vichu8888. The program now works but I still want to confirm.

In the constructor 1
array3d::array3d (int u, int v, int x)
I am creating the array using new[]. Even then i don't need a destructor?
closed account (zb0S216C)
vichu8888 wrote:
"so take out that destructor and you didnt implement the default constructor."

1. Leave the destructor where it is.
2. He/she did implement the default constructor.

@s1729: If your class has a pointer that refers to dynamically allocated memory, then you need to free that memory at some point before the class object leaves its scope. The general rule is if you've overloaded one of these:

-- Copy-assignment operator
-- Destructor
-- Copy constructor

...then you need to overload the two that you didn't overload. For example, let's say you overload the copy-constructor; you would need to overload both the destructor and copy-assignment operator. This is know as the Rule of Three[1, Rule of Three]. It's normal to deallocate memory within the destructor, but this isn't always what the programmer wants.

References:
[1, Rule of Three] http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)


Wazzak
Last edited on
Many thanks Wazzak, for directing to the Rule of three. I managed to solve the problem.
Hi wazzaq,

Which is the default constructor? Because I can see only normal constructor.
closed account (zb0S216C)
A default constructor is simply a constructor with either no formal parameters, or, a constructor with formal parameters but all have default actual parameters. If no explicit constructor call is made when an object is created, the compiler will automatically invoke the default constructor. However, there are no normal constructors, only:

-- Default constructor
-- Copy constructor
-- Conversion constructor
-- Move constructor (C++11)

Wazzak
Last edited on
I thought a "default constructor" was the constructor generated automatically when the user didn't implement any.
hmmm k. thanks for that info
closed account (zb0S216C)
@Catfish2: No. The compiler-generated default constructor is called a trival constructor, which basically means "do nothing".

Wazzak
Trivial default ctor is only a special case of the implicitly-defined default constructor. See http://en.cppreference.com/w/cpp/language/default_constructor for example.
Framework wrote:
The compiler-generated default constructor is called a trival constructor, which basically means "do nothing".


An implicitly generated default constructor (a defaulted default constructor in standard parlance) may be a trivial constructor, and it may not.

[12.1.5] A default constructor is trivial if it is not user-provided and if:
— its class has no virtual functions (10.3) and no virtual base classes (10.1), and
— no non-static data member of its class has a brace-or-equal-initializer, and
— all the direct base classes of its class have trivial default constructors, and
— for all the non-static data members of its class that are of class type (or array thereof), each such class has a trivial default constructor.


Which means the default constructor for the following classes, although defaulted are not trivial:
1
2
3
class a { std::string a; };
class b { virtual go(); };
class d : public a {} ;



For completeness:
[12.7.12] A copy/move constructor for class X is trivial if it is not user-provided and if
— class X has no virtual functions (10.3) and no virtual base classes (10.1), and
— the constructor selected to copy/move each direct base class subobject is trivial, and
— for each non-static data member of X that is of class type (or array thereof), the constructor selected to copy/move that member is trivial; otherwise the copy/move constructor is non-trivial.


[12.4.5] A destructor is trivial if it is not user-provided and if:
— the destructor is not virtual,
— all of the direct base classes of its class have trivial destructors, and
— for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor.
Otherwise, the destructor is non-trivial.
Last edited on
Topic archived. No new replies allowed.