Board index » cppbuilder » Dynamic allocation of arrays.

Dynamic allocation of arrays.


2006-10-10 12:42:08 AM
cppbuilder20
Hi,
I wish to define an array of pointers to a class. I do not know
the size of the array until run time. I have looked at the
help text and I think something like this should work:-
TMbClass **MbClasses;
Num = GetNewNumber();
MbClasses = new TMbClass*[Num];
Is this right?
When I inspect MbClasses, it displays the data as defined in my class, but doesn't give address for the methods and I am
therefore confused whether I have actually created the array of
pointers to the objects.
Thanks.
 
 

Re:Dynamic allocation of arrays.

"JB" < XXXX@XXXXX.COM >writes:
Quote
I wish to define an array of pointers to a class. I do not know
the size of the array until run time. I have looked at the
help text and I think something like this should work:-

TMbClass **MbClasses;

Num = GetNewNumber();
MbClasses = new TMbClass*[Num];

Is this right?
Yes, but not particularly easy to deal with.
Unless you have very good reason not to, use a Standard Library
container such as
std::vector<TMbClass*>MbClasses(Num);
If MbClasses should own the TMbClass objects that its elements refer
to, change the value type to an appropriate "smart pointer" type such
as
std::vector< boost::shard_ptr<TMbClass>>MbClasses(Num);
(cf. www.boost.org/).
 

Re:Dynamic allocation of arrays.

"JB" < XXXX@XXXXX.COM >wrote in message
Quote
Is this right?
So far, yes. Just make sure that you free the array when you are done using
it:
delete[] MbClasses;
Quote
When I inspect MbClasses, it displays the data as defined in my class,
but doesn't give address for the methods and I am therefore confused
whether I have actually created the array of pointers to the objects.
Yes, you have created an array of pointers. But you have not actually
assigned the pointers to point at any objects yet. You have to do that
separately after creating the array:
for(int i = 0; i < Num; ++i)
MbClasses[i] = some object here ...;
If the objects are created with the 'new' operator, then make sure you free
them before freeing the array:
TMbClass **MbClasses;
Num = GetNewNumber();
MbClasses = new TMbClass*[Num];
for(int i = 0; i < Num; ++i)
MbClasses[i] = new TMbClass(...);
// use MbClasses as needed ...
for(int i = 0; i < Num; ++i)
delete MbClasses[i];
delete[] MbClasses;
On the other hand, if you want the array to hold actual object instances
that are create anew each time, and not have to create them separately, then
you should create an array of actual objects, not an array of pointers to
objects:
TMbClass *MbClasses;
Num = GetNewNumber();
MbClasses = new TMbClass[Num];
//...
delete[] MbClasses;
Gambit
 

{smallsort}

Re:Dynamic allocation of arrays.

JB wrote:
Quote
Hi,
I wish to define an array of pointers to a class. I do not know
the size of the array until run time. I have looked at the
help text and I think something like this should work:-

TMbClass **MbClasses;

Num = GetNewNumber();
MbClasses = new TMbClass*[Num];

Is this right?
Do it the easy way:
include <vector>
typedef std::vector <TMbClasses *>VMbClasses;
VMbClasses MyMbClasses;
etc
--
Liz
Please check the newsgroup guidelines and general netiquette
info.borland.com/newsgroups/guide.html
info.borland.com/newsgroups/guide.html
info.borland.com/newsgroups/netiquette.html
 

Re:Dynamic allocation of arrays.

Quote
JB wrote:
>Hi,
>I wish to define an array of pointers to a class. I do not know the size of the array until run time.
"Liz" < XXXX@XXXXX.COM >wrote:
Do it the easy way:

include <vector>

typedef std::vector <TMbClasses *>VMbClasses;

VMbClasses MyMbClasses;

Thanks for each of the responses to this. I was a C programmer
in the old days and have transferred to C++. I did not know
about the container classes. I spent today getting to grips
with them - should be able to do some good stuff with them.
The help text says that if a user defined element is used, it
must have a copy constructor. Am I right in thinking that this
is a constructor for the class which takes a pointer to an
object of it's own type, as the parameter and creates the new
object as a direct copy of the object passed to it? Hope I
have explained this OK.
I appreciate the help.
 

Re:Dynamic allocation of arrays.

"JB" < XXXX@XXXXX.COM >writes:
Quote
Thanks for each of the responses to this. I was a C programmer
in the old days and have transferred to C++. I did not know
about the container classes. I spent today getting to grips
with them - should be able to do some good stuff with them.
The help text says that if a user defined element is used, it
must have a copy constructor. Am I right in thinking that this
is a constructor for the class which takes a pointer to an
object of it's own type, as the parameter and creates the new
object as a direct copy of the object passed to it? Hope I
have explained this OK.
Almost. A copy constructor takes a reference to another instance,
which is used as a prototype for how to create this new object.
Unless you have very unusual requirements, the signature of the copy
constructor is:
class x
{
public:
x(x const & other); // copy constructor
};
While a pointer and reference are very similar, the easiest way to
seperate them is by thinking "references use a dot, pointers use an
arrow." There is, of course more difference, but that is
syntactically the difference.
Other differences include:
* pointers can be null, references must be initialized to a valid
object
* pointers can be changed, references cannot be re-bound
* pointers need to be explicitly dereferenced, references do not
I'm probably missing other aspects, but for a quick off-the-cuff list,
this is probably enough to get you going.
--
Chris (TeamB);
 

Re:Dynamic allocation of arrays.

"JB" < XXXX@XXXXX.COM >writes:
Quote
The help text says that if a user defined element is used, it must
have a copy constructor.
Note that this doesn't necessarily mean work. Not for you anyway.
If the class doesn't declare a copy-constructor, the compiler will
generate one for the class if objects of the class are
copy-constructed. The generated copy-constructor simply copies the
class members one by one using their copy-constructor. This means that
for most well behaved classes, you won't have to write a
copy-constructor of your own.
 

Re:Dynamic allocation of arrays.

XXXX@XXXXX.COM (Thomas Maeder [TeamB]) wrote:
Quote
If the class doesn't declare a copy-constructor, the compiler
will generate one for the class if objects of the class are
copy-constructed. The generated copy-constructor simply
copies the class members one by one using their copy-
constructor. This means that for most well behaved classes,
you won't have to write a copy-constructor of your own.
Does this mean that if I don't have a "well behaved class" and a copy-contructor cannot be generated, it will result in a compiler error?
Thanks.
 

Re:Dynamic allocation of arrays.

JB wrote:
Quote
Does this mean that if I don't have a "well behaved
class" and a copy-contructor cannot be generated,
it will result in a compiler error?
If your class has a member that is a pointer to (address of) some
data, the compiler-generated copy constructor will copy the value of
the pointer (the address of the data), but will not copy the data.
If you later delete the original copy of the object along with the
data that the member points to, the copy in the container will point
to memory that is no longer allocated. That is a problem at runtime
(but not likely to result in a compiler error), so for such a class
you need to write a copy constructor that also makes a copy of the
data (or does reference counting to handle a shared data buffer).
- Leo
 

Re:Dynamic allocation of arrays.

Leo Siefert < XXXX@XXXXX.COM >writes:
Quote
so for such a class you need to write a copy constructor that also
makes a copy of the data (or does reference counting to handle a
shared data buffer).
My suggestion would be to avoid owning dynamically allocated resources
through "raw" pointers.
Smart pointers should be used instead; they will either prevent the
the copy-constructor from being generated or make sure that the
generated copy-constructor does the right thing.
 

Re:Dynamic allocation of arrays.

XXXX@XXXXX.COM (Thomas Maeder [TeamB]) wrote:
Quote
Smart pointers should be used instead; they will either
prevent the the copy-constructor from being generated or make
sure that the generated copy-constructor does the right thing.
This is getting even more mysterious. What is a "smart" pointer as opposed to a "raw" pointer?
Thanks.
 

Re:Dynamic allocation of arrays.

"JB" < XXXX@XXXXX.COM >writes:
Quote
XXXX@XXXXX.COM (Thomas Maeder [TeamB]) wrote:
>Smart pointers should be used instead; they will either
>prevent the the copy-constructor from being generated or make
>sure that the generated copy-constructor does the right thing.

This is getting even more mysterious. What is a "smart" pointer as
opposed to a "raw" pointer? Thanks.
It is a simple class that wraps a pointer, but that implements logic
to manage the resource that it owns.
For example, the standard library has one called std::auto_ptr, which
will hold a pointer and when the object goes out of scope, will
immediately and automatically delete the pointer. For example:
// for auto_ptr
#include <memory>
class Something_Cool
{
public:
void bar();
//...
};
void foo()
{
std::auto_ptr<Something_Cool>ptr(new Something_Cool);
ptr->bar();
}
Notice that in function foo(), ptr is allocated, but not explicitly
deleted. The auto_ptr guarantees that the object will be deleted,
even if the function bar() throws an exception.
There are other types of "smart pointers" too, such as those that
implement reference counting, and automatically manage the lifetime by
deleting the underlying object only when the refcount actually drops
to zero. (For example, see the boost smart pointer library, at
www.boost.org.)
--
Chris (TeamB);
 

Re:Dynamic allocation of arrays.

Chris Uzdavinis (TeamB) < XXXX@XXXXX.COM >wrote:
Quote
For example, the standard library has one called std::auto_ptr, which
will hold a pointer and when the object goes out of scope, will
immediately and automatically delete the pointer. For example:
The original poster should note that using a std::auto_ptr in a vector
is dangerous upon, if you can even get it to compile. The better
solution (as you allude to) is to use one of the boost smart pointers
(available from www.boost.org).
However, I'm not sure the original poster has been asked whether the
pointers are even necessary.
Perhaps
std::vector <TMbClasses>MyMbClasses;
would work better. The actual objects are in the vector.
Alan Bellingham
--
ACCU Conference: 11-14 April 2007 - Paramount Oxford Hotel
 

Re:Dynamic allocation of arrays.

Alan Bellingham < XXXX@XXXXX.COM >writes:
Quote
The original poster should note that using a std::auto_ptr in a vector
is dangerous upon, if you can even get it to compile. The better
Yes, I probably should have mentioned that, but I wasn't thinking
about using the smart pointers in a vector... just explaining what
they were. IMHO, for practical purposes, auto_ptr is best on the
stack, not in other objects. There are a few too many subtleties for
my liking to have auto_ptr members, in any case.
Boost.shared_ptr is a nice class, and soon to be found in the C++
standard library.
Quote
Perhaps

std::vector <TMbClasses>MyMbClasses;

would work better. The actual objects are in the vector.
Agreed. When user-controlled dynamic memory can be avoided, it's
good to strive to do so.
--
Chris (TeamB);
 

Re:Dynamic allocation of arrays.

JB wrote:
Quote
This is getting even more mysterious. What is a "smart" pointer as
opposed to a "raw" pointer?
Google is your friend (and so is boost!)
www.boost.org/libs/smart_ptr/smart_ptr.htm
--
Liz
Please check the newsgroup guidelines and general netiquette
info.borland.com/newsgroups/guide.html
info.borland.com/newsgroups/guide.html
info.borland.com/newsgroups/netiquette.html