473,322 Members | 1,718 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

Destroying an array of arrays

Hello -

I have two classes A and B as follows:

class B{
public:
~B(){ cout << "destroying B" << endl; }
};

class A{
public:
~A(){ cout << "destroying A" << endl; }
B** b;
};

When used in my main function as follows:

int main()
{
A a;
a.b = new B*[4];

for(int i = 0; i < 3; i++)
{
a.b[i] = new B;
}

}

Only the destructor of A is called.

<ramble>
Do I need to wrap B in an intermediate class before it can be
destroyed? I sort of have the idea that destructors are not called
over(?) a pointer
</ramble>

Thanks,

- Olumide

Nov 30 '06 #1
4 2675

Olumide wrote:
Hello -

I have two classes A and B as follows:

class B{
public:
~B(){ cout << "destroying B" << endl; }
};

class A{
public:
~A(){ cout << "destroying A" << endl; }
B** b;
};

When used in my main function as follows:

int main()
{
A a;
a.b = new B*[4];

for(int i = 0; i < 3; i++)
{
a.b[i] = new B;
}

}

Only the destructor of A is called.
Well yes, the local copy of A is destroyed at the end of the scope it
is in since its a local variable.
If you allocate anything with new, it's your responsability to
deallocate with delete, or as in this case, delete [].
>
<ramble>
Do I need to wrap B in an intermediate class before it can be
destroyed? I sort of have the idea that destructors are not called
over(?) a pointer
</ramble>
What? the pointer is used to track the allocations you are required to
deallocate manually. The compiler has no way to deallocate since new
removes *all* responsability that the compiler has to free up those
array blocks.

Why not use std::vector< std::vector to do this? You wouldn't need to
allocate anything on the heap. And if really want to use pointers, then
do without the B** indirection. Pointers are a pain enough as it is.

Consider using templates as follows in the case you prefer primitive
arrays.

#include <iostream>

class B {
public:
B() { std::cout << "B()\n"; }
~B() { std::cout << "~B()\n"; }
};

template< typename T, // element type
const size_t Arrays, // number of arrays
const size_t Size // size of each array
class A {
T* array[Arrays];
public:
A() { std::cout << "A()\n"; }
~A() { std::cout << "~A()\n"; }
void allocate()
{
for(size_t i = 0; i < Arrays; ++i)
{
array[i] = new T[Size];
}
}
void deallocate()
{
for(size_t i = 0; i < Arrays; ++i)
{
delete [] array[i];
}
}
};

int main()
{
A< B , 2, 2 a; // 2 arrays of 2 elements each
a.allocate();
a.deallocate();
}

/*
A()
B()
B()
B()
B() // thats 2 x 2 = 4
~B()
~B()
~B()
~B()
~A()
*/

Note that T* array[Arrays] is created as an array of pointers to
nothing. That array gets zapped along with the a variable in main. So
once you get the above working correctly, you can stick allocate() in
ctor and deallocate() in d~tor.

Nov 30 '06 #2

Olumide wrote:
class A{
public:
~A(){ cout << "destroying A" << endl; }
B** b;
};
...
int main()
{
A a;
...
Only the destructor of A is called.
The object "a" of the class "A" has auto storage modifier and C++
comipler manages memory of auto objects (calls its destructors) and
places the objects to stack. Your class A has the "b" member of the
class "B**"(pointer to pointer to B). The class "B**" is not the same
as the class "B" (predefined class "B**" has no destructor "{ cout <<
"destroying B**" << endl; }" ) and deleting the pointer not forced
deleting an object, which it point.

You need destructor of A like this:
private:
enum { arr_size=4 };
do_destruct()throw()
{
for( int i = 0; i<(arr_size-1) ; ++i ) { delete a.b[i]; a.b[i]
= 0; }
delete[] b; b=0;
}

public:
~A(){
do_destruct();
cout << "destroying A" << endl;
}

In the class A you use a C-style arrays. It is nothing wrong "in
general", but you _must not_ allow external memory allocation for the
class.

Memory management (and mostl other management) must be incapsulated by
your class A and details of memory allocation must be hidden by special
part of class interface, with the help of some methods, for instance,
with the help of std methods - constructor and destructor or by your
own virtual methods - create()/destroy().

This is no good
a.b = new B*[4];

for(int i = 0; i < 3; i++)
{
a.b[i] = new B;
}
You can do like this
enum { arr_size=4 };
A()throw(exception&):b(0)
{
b = new B*[arr_size];
for(int i = 0; i<(arr_size-1) ; ++i) b[i]=0; //it is realy easy
to foget

try{ for(int i = 0; i < (arr_size-1); ++i) b[i] = new B;
}catch(...) { do_destruct(); throw; }
}

If you have STL implementet for you C++ compiler and target, you can
use vector<and so on insted of C-style arrays. You can also make you
own light class "my_array" instead of vector<>, in order to place code
of memory allocation methods in one class.

Nov 30 '06 #3

Oops.
do_destruct()throw()
{
for( int i = 0; i<(arr_size-1) ; ++i ) { delete a.b[i]; a.b[i] = 0; }
delete[] b; b=0;
}
I have written a hard error, much better
do_destruct()throw()
{
if(b) for( int i = 0; i<(arr_size-1) ; ++i ) { delete b[i]; b[i] = 0;
}
delete[] b; b=0;
}

The error tells us that we must be very accurate especially while using
C-style arrays, else hard errors can appear and that any class, already
have encapsuleted memory allocation, is much suitable instead of direct
C-style arrays control.

Nov 30 '06 #4
Grizlyk wrote:
for( int i = 0; i<(arr_size-1) ; ++i ) { delete a.b[i]; a.b[i] = 0; }
And error again.

One kind man told me, that I have done an error again. It is realy
unpleasant error in "for" condition, must be
for(int i=0; i<arr_size; ++i)

It is often better to use true name insted of "arr_size", for example:
"rooms", "my_cars" and so on, but it can be _not_ more easy to check
the type of erorrs with the help of the name .

There are too many simplest errors in the short piece of code i have
done, but it would be better to correct them :).

Dec 6 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

13
by: Noah Spitzer-Williams | last post by:
Hello guys, I would like to do something seemingly simple: find out if an element in an array that is passed to my function exists. I used to think I could just do: if (arr) ... However, if...
5
by: JezB | last post by:
What's the easiest way to concatenate arrays ? For example, I want a list of files that match one of 3 search patterns, so I need something like DirectoryInfo ld = new DirectoryInfo(searchDir);...
1
by: Craig | last post by:
Hey Everyone - I'm trying to determine the fastest way of moving array information around and could use some help. Here's the setup: Class A stores a DateTime and an amount (a payment)....
7
by: cdg | last post by:
Would anyone explain how to return an array that wasn`t passed from "main" using a pointer. I'm not understanding how scope and memory are involved in this. However, I do know that there are two...
4
by: Bundy | last post by:
I am trying to create a function that executes all the functions listed in an array. I cannot get it to work. <html> <body> <script language="JavaScript"> var length_of_array = 2; var...
3
by: arnuld | last post by:
Stroustrup says: "Arrays are not self describing because the number of elements of an Array is not guarnteed to be stored with Array" "this implies that o traverse an Array that does not...
37
by: Erwin Lindemann | last post by:
If a VLA appears within a loop body, it seems the behavior is different with two different compilers I tried. I looked at the standard text, but couldn't find a definite answer there either. ...
10
by: Ahmad Humayun | last post by:
Whats the difference between: char str1 = "wxyz"; char* str2 = "abcd"; I can do this: str2 = str1 but I can't do this: str1 = str2
14
by: =?Utf-8?B?RWR3YXJk?= | last post by:
Hi everybody, To me the following code shouldn't work but it does ! Imports system.String Dim x As String="This,is,a,test" Dim y(1) As String y=x.Split(",") TextBox1.text=y(3) why "Y" which is...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.