How to initialize array?

T

toton

Hi,
In C++ when I initialize an array it, also initializes the class that
it contains, which calls the default constructor. However, I want to
initialize the array only (i.e reserve the space) and use my specific
constructor to initialize the class. How to do it without using malloc?


Something like Point* pt = new Point[N]; I want it to reserve the
space for N points only, and not to call default constructor. I dont
have a default constructor. Infact the Point is immutable, i.e once it
is created , its x & y values are not supposed to be changed. So I want
to create it and place in the array. Note the array size to be fixed at
runtime only. Is malloc(N*sizeof(Point)) is a safe way to do it?
Even if I reserve the space for N points, how to create the points?
Something like pt[0] = Point(3,4) will work?
Or I need placement new to put the actual Point in the proper
position.The Point class doesn't have a subclass, and wont have.


abir
 
M

Mehturt

toton napísal(a):
Hi,
In C++ when I initialize an array it, also initializes the class that
it contains, which calls the default constructor. However, I want to
initialize the array only (i.e reserve the space) and use my specific
constructor to initialize the class. How to do it without using malloc?

How about using std::vector?

class A
{
};
Something like Point* pt = new Point[N]; I want it to reserve the
space for N points only, and not to call default constructor. I dont
have a default constructor. Infact the Point is immutable, i.e once it
is created , its x & y values are not supposed to be changed. So I want
to create it and place in the array. Note the array size to be fixed at
runtime only. Is malloc(N*sizeof(Point)) is a safe way to do it?
Even if I reserve the space for N points, how to create the points?
Something like pt[0] = Point(3,4) will work?

v.push_back(new A(3,4));
 
K

Kai-Uwe Bux

toton said:
Hi,
In C++ when I initialize an array it, also initializes the class that
it contains, which calls the default constructor. However, I want to
initialize the array only (i.e reserve the space) and use my specific
constructor to initialize the class. How to do it without using malloc?

Your need for this may indicate a deeper problem. To answer the technical
question up front: you need to use malloc (or some other raw memory
allocation mechanism, e.g., based on new) and placement new afterwards to
construct your objects. You could place all this code in what the standard
calls an "allocator".

Something like Point* pt = new Point[N]; I want it to reserve the
space for N points only, and not to call default constructor. I dont
have a default constructor. Infact the Point is immutable, i.e once it
is created , its x & y values are not supposed to be changed.

That could be a serious design flaw. You made a class that is not
assignable. This rules out the many uses of standard containers.
So I want
to create it and place in the array. Note the array size to be fixed at
runtime only. Is malloc(N*sizeof(Point)) is a safe way to do it?
Even if I reserve the space for N points, how to create the points?
Something like pt[0] = Point(3,4) will work?
Or I need placement new to put the actual Point in the proper
position.The Point class doesn't have a subclass, and wont have.

If you don't plan on polymorphic points, I do not see any reason why your
point class shouldn't "do as int does". Make it copy-constructible,
assignable, if you want, make all other member functions constant (if you
plan on having any!). Once your class behaves like a class with good value
semantics, you can use all the standard containers like std::vector and
std::map to keep track of your points. This will at once eliminate the need
to use raw arrays in the first place and also rid your program of a lot of
unnecessary low-level code.


Best

Kai-Uwe Bux
 
A

Alan Johnson

toton said:
Hi,
In C++ when I initialize an array it, also initializes the class that
it contains, which calls the default constructor. However, I want to
initialize the array only (i.e reserve the space) and use my specific
constructor to initialize the class. How to do it without using malloc?


Something like Point* pt = new Point[N]; I want it to reserve the
space for N points only, and not to call default constructor. I dont
have a default constructor. Infact the Point is immutable, i.e once it
is created , its x & y values are not supposed to be changed. So I want
to create it and place in the array. Note the array size to be fixed at
runtime only. Is malloc(N*sizeof(Point)) is a safe way to do it?
Even if I reserve the space for N points, how to create the points?
Something like pt[0] = Point(3,4) will work?
Or I need placement new to put the actual Point in the proper
position.The Point class doesn't have a subclass, and wont have.


abir

Perhaps you are trying to do something like this?

#include <cstddef> // for size_t
#include <new>

class Point
{
} ;

int main()
{
const std::size_t N = 25 ;

std::size_t count = 0 ;
Point * p = 0 ;


// Allocate some uninitialized memory.
p = static_cast<Point *>(operator new(sizeof(Point) * N)) ;

// Construct some Points. (using placement new)
for (count = 0; count < N; ++count)
new (p+count) Point ;

// Destruct the points. (explicitly call destructor)
for (count = 0; count <= N; ++count)
p[count].~Point() ;

// Release the memory.
operator delete(p) ;
}
 
T

toton

Kai-Uwe Bux said:
Your need for this may indicate a deeper problem. To answer the technical
question up front: you need to use malloc (or some other raw memory
allocation mechanism, e.g., based on new) and placement new afterwards to
construct your objects. You could place all this code in what the standard
calls an "allocator".
stl vector is not suitable as it can be resized. I want constant size
container, and size is available only at runtime (that rules out boost
array). Any such container class is there?
Something like Point* pt = new Point[N]; I want it to reserve the
space for N points only, and not to call default constructor. I dont
have a default constructor. Infact the Point is immutable, i.e once it
is created , its x & y values are not supposed to be changed.

That could be a serious design flaw. You made a class that is not
assignable. This rules out the many uses of standard containers.
Yes, I dont want anyone accedentally assign the point to a new one,
change it's data etc. Thus once the point is created, only option to it
is to get destroyed. One freind class for the container will create the
points in the buffer & remove from it when needed. Any other needs the
point can get it only through a const reference, No other way should be
available to change it or even copy it.
How STL vector reserves space? using malloc or any other way? as it
doesn't call default constructor for the class. They saves the Point in
adjacent memory block within the limit of reserve? when using as
vector<Point>, NOT vector<Point*>.
when the vector reserve limit exceeds it copy the existing data to a
new place or try to check if additional memory can be reserved in
place, like the TLB trick is done in realloc of c in glibc? I am not
geting a clear idea from the vector source code.... it looks too
complex.
I want a replacement of vector but of fixed size at runtime. any such
class is there?
So I want
to create it and place in the array. Note the array size to be fixed at
runtime only. Is malloc(N*sizeof(Point)) is a safe way to do it?
Even if I reserve the space for N points, how to create the points?
Something like pt[0] = Point(3,4) will work?
Or I need placement new to put the actual Point in the proper
position.The Point class doesn't have a subclass, and wont have.

If you don't plan on polymorphic points, I do not see any reason why your
point class shouldn't "do as int does". Make it copy-constructible,
assignable, if you want, make all other member functions constant (if you
plan on having any!). Once your class behaves like a class with good value
semantics, you can use all the standard containers like std::vector and
std::map to keep track of your points. This will at once eliminate the need
to use raw arrays in the first place and also rid your program of a lot of
unnecessary low-level code.


Best

Kai-Uwe Bux
 
T

toton

Alan said:
toton said:
Hi,
In C++ when I initialize an array it, also initializes the class that
it contains, which calls the default constructor. However, I want to
initialize the array only (i.e reserve the space) and use my specific
constructor to initialize the class. How to do it without using malloc?


Something like Point* pt = new Point[N]; I want it to reserve the
space for N points only, and not to call default constructor. I dont
have a default constructor. Infact the Point is immutable, i.e once it
is created , its x & y values are not supposed to be changed. So I want
to create it and place in the array. Note the array size to be fixed at
runtime only. Is malloc(N*sizeof(Point)) is a safe way to do it?
Even if I reserve the space for N points, how to create the points?
Something like pt[0] = Point(3,4) will work?
Or I need placement new to put the actual Point in the proper
position.The Point class doesn't have a subclass, and wont have.


abir

Perhaps you are trying to do something like this?

#include <cstddef> // for size_t
#include <new>

class Point
{
} ;

int main()
{
const std::size_t N = 25 ;

std::size_t count = 0 ;
Point * p = 0 ;


// Allocate some uninitialized memory.
p = static_cast<Point *>(operator new(sizeof(Point) * N)) ;

// Construct some Points. (using placement new)
for (count = 0; count < N; ++count)
new (p+count) Point ;

// Destruct the points. (explicitly call destructor)
for (count = 0; count <= N; ++count)
p[count].~Point() ;

// Release the memory.
operator delete(p) ;
}

Yes. I am trying to do exactly something like this. except some additional feature like the array is a circular buffer of fixed size, and the whole thing is a class. And may be occationally (very rarely) i will change the size of the circular buffer, when it can't acomodate the minimum requirement. Point is a single class, not in object hierarchy.

My additional questions,
1) Any problem with this kind of code? any known danger for any
platform (not the programming errors, any danger even with correct
programming)?
2) do i need to have a placement new ctor for Point? or default will
work?

Thanks
 
K

Kai-Uwe Bux

toton said:
Kai-Uwe Bux said:
Your need for this may indicate a deeper problem. To answer the technical
question up front: you need to use malloc (or some other raw memory
allocation mechanism, e.g., based on new) and placement new afterwards to
construct your objects. You could place all this code in what the
standard calls an "allocator".
stl vector is not suitable as it can be resized. I want constant size
container, and size is available only at runtime (that rules out boost
array). Any such container class is there?
Something like Point* pt = new Point[N]; I want it to reserve the
space for N points only, and not to call default constructor. I dont
have a default constructor. Infact the Point is immutable, i.e once it
is created , its x & y values are not supposed to be changed.

That could be a serious design flaw. You made a class that is not
assignable. This rules out the many uses of standard containers.
Yes, I dont want anyone accedentally assign the point to a new one,
change it's data etc. Thus once the point is created, only option to it
is to get destroyed. One freind class for the container will create the
points in the buffer & remove from it when needed. Any other needs the
point can get it only through a const reference, No other way should be
available to change it or even copy it.

I understand what you want, you already explained that in your first post. I
just think, you want the wrong thing and what you are doing is a
BadIdea(tm). The point class you propose is unfriendly to the customer, and
if used, will trigger questions in this very newsgroup as to how one can
circumvent the protection mechanisms you built in. Not trusting that other
programmers know what they are doing is causing all sorts of trouble. Your
current difficulties are just one example.

Look at it this way: the standard library creates reasonable expectations on
the part of your fellow programmers as to how well-behaved classes with
value semantics should be designed (in particular, they need to be default
constructible, assignable, and copy constructible). By creating a class
that breaks these expectations, you are making your own life and the life
of anybody using your class more difficult.

How STL vector reserves space? using malloc or any other way? as it
doesn't call default constructor for the class. They saves the Point in
adjacent memory block within the limit of reserve? when using as
vector<Point>, NOT vector<Point*>.
when the vector reserve limit exceeds it copy the existing data to a
new place or try to check if additional memory can be reserved in
place, like the TLB trick is done in realloc of c in glibc? I am not
geting a clear idea from the vector source code.... it looks too
complex.

Standard containers do all memory management through allocators. Read up on
those in your C++ books. The standard library provides one, std::allocator,
that is used as the default allocator by all containers. You can, however,
always provide your own allocator.

When std::vector exceeds its current capacity, it reallocates memory and
copies the objects to the new location. Again, the allocator is used to
handle destruction and construction of objects and management of raw
memory.
I want a replacement of vector but of fixed size at runtime. any such
class is there?

Not that I know of.


[snip]


Best

Kai-Uwe Bux
 
T

toton

Kai-Uwe Bux said:
toton said:
Kai-Uwe Bux said:
toton wrote:

Hi,
In C++ when I initialize an array it, also initializes the class that
it contains, which calls the default constructor. However, I want to
initialize the array only (i.e reserve the space) and use my specific
constructor to initialize the class. How to do it without using malloc?

Your need for this may indicate a deeper problem. To answer the technical
question up front: you need to use malloc (or some other raw memory
allocation mechanism, e.g., based on new) and placement new afterwards to
construct your objects. You could place all this code in what the
standard calls an "allocator".
stl vector is not suitable as it can be resized. I want constant size
container, and size is available only at runtime (that rules out boost
array). Any such container class is there?
Something like Point* pt = new Point[N]; I want it to reserve the
space for N points only, and not to call default constructor. I dont
have a default constructor. Infact the Point is immutable, i.e once it
is created , its x & y values are not supposed to be changed.

That could be a serious design flaw. You made a class that is not
assignable. This rules out the many uses of standard containers.
Yes, I dont want anyone accedentally assign the point to a new one,
change it's data etc. Thus once the point is created, only option to it
is to get destroyed. One freind class for the container will create the
points in the buffer & remove from it when needed. Any other needs the
point can get it only through a const reference, No other way should be
available to change it or even copy it.

I understand what you want, you already explained that in your first post. I
just think, you want the wrong thing and what you are doing is a
BadIdea(tm). The point class you propose is unfriendly to the customer, and
if used, will trigger questions in this very newsgroup as to how one can
circumvent the protection mechanisms you built in. Not trusting that other
programmers know what they are doing is causing all sorts of trouble. Your
current difficulties are just one example.

Look at it this way: the standard library creates reasonable expectations on
the part of your fellow programmers as to how well-behaved classes with
value semantics should be designed (in particular, they need to be default
constructible, assignable, and copy constructible). By creating a class
that breaks these expectations, you are making your own life and the life
of anybody using your class more difficult.

How STL vector reserves space? using malloc or any other way? as it
doesn't call default constructor for the class. They saves the Point in
adjacent memory block within the limit of reserve? when using as
vector<Point>, NOT vector<Point*>.
when the vector reserve limit exceeds it copy the existing data to a
new place or try to check if additional memory can be reserved in
place, like the TLB trick is done in realloc of c in glibc? I am not
geting a clear idea from the vector source code.... it looks too
complex.

Standard containers do all memory management through allocators. Read up on
those in your C++ books. The standard library provides one, std::allocator,
that is used as the default allocator by all containers. You can, however,
always provide your own allocator.

When std::vector exceeds its current capacity, it reallocates memory and
copies the objects to the new location. Again, the allocator is used to
handle destruction and construction of objects and management of raw
memory.
I want a replacement of vector but of fixed size at runtime. any such
class is there?

Not that I know of.


[snip]


Best
I want something like Alan Johnson had posted in this thread. How
exactly same thing can be done using stl container? If it provides, I
will use it. Otherwise I have to use my own. Can the same be done with
my allocator and any other facility?
About the Point class, I am no way breaking the rule. Only , I want it
to be immutable, and should me initialized in the way I want, not by
default constructor. That's my requirement, and I can't change
requirement to allow design to come. And making a class object
immutable doesn't break rule, it enforses object data hiding, and helps
in threading apart from other (you can check books like effective C++
or Effective Java about immutable objects).
I have no objection against using stl, if a stl container provides my
requirement. I will use it.
my requirements are:
1) the Points should be initialized using my constructor rather than
default (rules out array with new), and should not be changed after
that.
2) my point buffer is of fixed size (raw array works but vector is not
fixed size, i may need a wrapper of vector)
3) I want points to be initialized in adjacent memory location. Thus
not want something like vector<Point*> , rathjer want vector<Point>

How to do it usng STL? (better check Alan Johnson's post in the thread,
it perfectly suits me, except people say array is evil & placement new
is bad. just an equivalend stl replacement will work for me.)

thanks for replying ...
abir
abir
 
A

Alf P. Steinbach

* toton:
In C++ when I initialize an array it, also initializes the class that
it contains, which calls the default constructor. However, I want to
initialize the array only (i.e reserve the space) and use my specific
constructor to initialize the class. How to do it without using malloc?

static Point const points[] = {{1,2}, {3,4}, {5,6}};

Something like Point* pt = new Point[N]; I want it to reserve the
space for N points only, and not to call default constructor. I dont
have a default constructor. Infact the Point is immutable, i.e once it
is created , its x & y values are not supposed to be changed. So I want
to create it and place in the array. Note the array size to be fixed at
runtime only.

Here you have three partially incompatible requirements:

* Immutable Point.
* Array size determined at run-time.
* No default constructor.

When you don't know the size of the array until run-time, and you have
no default constructor, how do you provide values to the initialization?

Well, you can do that by using indirection, which is the universal
answer to computer science problems:

struct IPointProvider
{
typedef std::auto_ptr<Point const> Ptr;
virtual Ptr instance( size_t i ) const = 0;
};

class Points
{
private:
typedef Point const* PointPtr;

std::vector<PointPtr> myPoints;

void initWith( IPointProvider const& provider )
{
for( size_t i = 0; i < myPoints.size(); ++i )
{
myPoints.at( i ) = provider.instance( i ).release();
}
}

void cleanUp()
{
for( size_t i = 0; i < n; ++i )
{
delete myPoints.at( i );
}
}

public:
Points( size_t n, IPointProvider const& provider )
: myPoints( n )
{
try
{
initWith( provider );
}
catch( ... )
{
cleanUp(); throw;
}
}

~Points() { cleanUp(); }

size_t size() const { return myPoints.size(); }

Point const& operator[]( size_t i ) const
{
return *myPoints.at( i );
}
};

Now you can say things like

IPointProvider const& randomPointProvider = ...;
Points points( 259, randomPointProvider );

std::cout << points[3].x << std::endl;

Is malloc(N*sizeof(Point)) is a safe way to do it?

No, use standard library collection classes such as std::vector.

Even if I reserve the space for N points, how to create the points?

See above. Your requirements cost quite a bit of efficiency. Whether
that's meaningful is impossible to say, since you provide no context
(what the problem /really/ is), but chances are it's not meaningful.

Something like pt[0] = Point(3,4) will work?

Not per your requirements: you have required that it should not work,
that Point is immutable.

If that's not what you want, then your stated requirements are incorrect.

Or I need placement new to put the actual Point in the proper
position.

No, use standard library collection classes such as std::vector.
 
K

Kai-Uwe Bux

toton said:
Kai-Uwe Bux said:
toton said:
Kai-Uwe Bux wrote:
toton wrote:

Hi,
In C++ when I initialize an array it, also initializes the class
that
it contains, which calls the default constructor. However, I want to
initialize the array only (i.e reserve the space) and use my
specific constructor to initialize the class. How to do it without
using malloc?

Your need for this may indicate a deeper problem. To answer the
technical question up front: you need to use malloc (or some other raw
memory allocation mechanism, e.g., based on new) and placement new
afterwards to construct your objects. You could place all this code in
what the standard calls an "allocator".

stl vector is not suitable as it can be resized. I want constant size
container, and size is available only at runtime (that rules out boost
array). Any such container class is there?

Something like Point* pt = new Point[N]; I want it to reserve the
space for N points only, and not to call default constructor. I dont
have a default constructor. Infact the Point is immutable, i.e once
it is created , its x & y values are not supposed to be changed.

That could be a serious design flaw. You made a class that is not
assignable. This rules out the many uses of standard containers.

Yes, I dont want anyone accedentally assign the point to a new one,
change it's data etc. Thus once the point is created, only option to it
is to get destroyed. One freind class for the container will create the
points in the buffer & remove from it when needed. Any other needs the
point can get it only through a const reference, No other way should be
available to change it or even copy it.

I understand what you want, you already explained that in your first
post. I just think, you want the wrong thing and what you are doing is a
BadIdea(tm). The point class you propose is unfriendly to the customer,
and if used, will trigger questions in this very newsgroup as to how one
can circumvent the protection mechanisms you built in. Not trusting that
other programmers know what they are doing is causing all sorts of
trouble. Your current difficulties are just one example.

Look at it this way: the standard library creates reasonable expectations
on the part of your fellow programmers as to how well-behaved classes
with value semantics should be designed (in particular, they need to be
default constructible, assignable, and copy constructible). By creating a
class that breaks these expectations, you are making your own life and
the life of anybody using your class more difficult.
[snip]

I want something like Alan Johnson had posted in this thread. How
exactly same thing can be done using stl container? If it provides, I
will use it. Otherwise I have to use my own. Can the same be done with
my allocator and any other facility?

You will have to roll your own code.
About the Point class, I am no way breaking the rule. Only , I want it
to be immutable, and should me initialized in the way I want, not by
default constructor. That's my requirement, and I can't change
requirement to allow design to come. And making a class object
immutable doesn't break rule, it enforses object data hiding, and helps
in threading apart from other (you can check books like effective C++
or Effective Java about immutable objects).

It may be good design in Java (where objects have reference semantics).
IMHO, immutable objects with value semantics are ill-advised in C++ since
the standard library and the built in types set a precedence. This is a
cultural thing. You are just running against expectations and you are
ignoring existing infrastructure. That is why you find that your design is
not supported by standard components. Had the designers of the standard
library made different choices, immutable objects with value semantics
might be a well-supported good design. There are no absolutes in this
matter: it's a cultural thing.

The point about threading, I can see. The one about data hiding is bogus.
Data is hidden by making the members private not by making the objects
immutable.

Anyway, since you say you cannot change the design requirements, this is a
mood point, on which we can agree to disagree.
I have no objection against using stl, if a stl container provides my
requirement. I will use it.
my requirements are:
1) the Points should be initialized using my constructor rather than
default (rules out array with new), and should not be changed after
that.
2) my point buffer is of fixed size (raw array works but vector is not
fixed size, i may need a wrapper of vector)
3) I want points to be initialized in adjacent memory location. Thus
not want something like vector<Point*> , rathjer want vector<Point>

How to do it usng STL?

You can't. STL containers do not fit your requirements.


Best

Kai-Uwe Bux
 
A

Alan Johnson

toton said:
Alan said:
toton said:
Hi,
In C++ when I initialize an array it, also initializes the class that
it contains, which calls the default constructor. However, I want to
initialize the array only (i.e reserve the space) and use my specific
constructor to initialize the class. How to do it without using malloc?


Something like Point* pt = new Point[N]; I want it to reserve the
space for N points only, and not to call default constructor. I dont
have a default constructor. Infact the Point is immutable, i.e once it
is created , its x & y values are not supposed to be changed. So I want
to create it and place in the array. Note the array size to be fixed at
runtime only. Is malloc(N*sizeof(Point)) is a safe way to do it?
Even if I reserve the space for N points, how to create the points?
Something like pt[0] = Point(3,4) will work?
Or I need placement new to put the actual Point in the proper
position.The Point class doesn't have a subclass, and wont have.


abir
Perhaps you are trying to do something like this?

#include <cstddef> // for size_t
#include <new>

class Point
{
} ;

int main()
{
const std::size_t N = 25 ;

std::size_t count = 0 ;
Point * p = 0 ;


// Allocate some uninitialized memory.
p = static_cast<Point *>(operator new(sizeof(Point) * N)) ;

// Construct some Points. (using placement new)
for (count = 0; count < N; ++count)
new (p+count) Point ;

// Destruct the points. (explicitly call destructor)
for (count = 0; count <= N; ++count)
p[count].~Point() ;

// Release the memory.
operator delete(p) ;
}

Yes. I am trying to do exactly something like this. except some additional feature like the array is a circular buffer of fixed size, and the whole thing is a class. And may be occationally (very rarely) i will change the size of the circular buffer, when it can't acomodate the minimum requirement. Point is a single class, not in object hierarchy.

My additional questions,
1) Any problem with this kind of code? any known danger for any
platform (not the programming errors, any danger even with correct
programming)?

In general you should try to avoid it, because you are taking into your
own hands something the compiler normally will do for you. This means
that you've introduced more opportunities for errors, inefficiencies, etc.

That said, you are the one that best knows the problem you are trying to
solve, and whether a solution that decouples allocation from
initialization is appropriate. If after considering all the possible
designs, it still seems like the best, then by all means use it.

One thing that you might need to watch out for is exception safety.
Constructors can and often do throw exceptions. You would want to
guarantee that for any object you've constructed with placement new, you
also call its destructor. In the example above, that might involve
doing something like:

try
{
for (count = 0; count < N; ++count)
new (p+count) Point ;
}
catch (...)
{
for (; count; --count)
p[count-1].~Point() ;
throw ;
}

This safely destructs any object that happens to get constructed, even
if an exception is thrown in the constructor. There is an additional
concern that the destructor could throw an exception, but typically the
approach taken is to assume that destructors don't throw (this is the
approach taken by the standard library).
2) do i need to have a placement new ctor for Point? or default will
work?

The default constructor works fine.
 
I

Ivan Vecerina

:
: Alan Johnson wrote:
: > toton wrote:
: > > Hi,
: > > In C++ when I initialize an array it, also initializes the class
that
: > > it contains, which calls the default constructor. However, I want to
: > > initialize the array only (i.e reserve the space) and use my
specific
: > > constructor to initialize the class. How to do it without using
malloc?
: > >
: > >
: > > Something like Point* pt = new Point[N]; I want it to reserve the
: > > space for N points only, and not to call default constructor. I dont
: > > have a default constructor. Infact the Point is immutable, i.e once
it
: > > is created , its x & y values are not supposed to be changed. So I
want
: > > to create it and place in the array. Note the array size to be fixed
at
: > > runtime only. Is malloc(N*sizeof(Point)) is a safe way to do it?
: > > Even if I reserve the space for N points, how to create the
points?
: > > Something like pt[0] = Point(3,4) will work?
: > > Or I need placement new to put the actual Point in the proper
: > > position.The Point class doesn't have a subclass, and wont have.
: > >
: > >
: > > abir
: > >
: >
: > Perhaps you are trying to do something like this?
: >
: > #include <cstddef> // for size_t
: > #include <new>
: >
: > class Point
: > {
: > } ;
: >
: > int main()
: > {
: > const std::size_t N = 25 ;
: >
: > std::size_t count = 0 ;
: > Point * p = 0 ;
: >
: >
: > // Allocate some uninitialized memory.
: > p = static_cast<Point *>(operator new(sizeof(Point) * N)) ;
: >
: > // Construct some Points. (using placement new)
: > for (count = 0; count < N; ++count)
: > new (p+count) Point ;

A caveat here is exception safety:
If any failure occurs during this operation (e.g. the
constructor of Point or another operation throws an
exception), you would want to destruct previously
constructed points and release the memory.

: > // Destruct the points. (explicitly call destructor)
: > for (count = 0; count <= N; ++count)
: > p[count].~Point() ;
: >
: > // Release the memory.
: > operator delete(p) ;
: > }
: Yes. I am trying to do exactly something like this. except some
: additional feature like the array is a circular buffer of fixed
: size, and the whole thing is a class. And may be occationally
: (very rarely) i will change the size of the circular buffer,
: when it can't acomodate the minimum requirement.
: Point is a single class, not in object hierarchy.

I remember a circular buffer had once been submitted to boost,
and accepted. But I couldn't find it on www.boost.org now.
Some standard library implementations may also include this as
an extension (http://www.google.com/search?q=circular deque).

Note that std::deque has many of the properties that you are
looking for (except for constness, I'll get back to it):
the address of inserted elements is never changed (except
if you explicitly insert a new point in the middle of the
sequence), and a deque can grow/expand as needed without
ever requiring relocation of its contents.

: My additional questions,
: 1) Any problem with this kind of code? any known danger for any
: platform (not the programming errors, any danger even with correct
: programming)?
Code such as the above can be written in a portable way,
but providing exception safety is especially tricky.
Best is to look for an existing implementation of a circular
buffer.

: 2) do i need to have a placement new ctor for Point? or default will
: work?
The default placement new operator will do.


This said, if I were you, I would use std::deque to
implement the buffer. I understand the benefit of
having non-mutable elements (Point-s), but couldn't
you obtain the same result by only returning
Point const& or Point const* from your buffer class ?


Regards,
Ivan
 
T

toton

In general you should try to avoid it, because you are taking into your
own hands something the compiler normally will do for you. This means
that you've introduced more opportunities for errors, inefficiencies, etc.

That said, you are the one that best knows the problem you are trying to
solve, and whether a solution that decouples allocation from
initialization is appropriate. If after considering all the possible
designs, it still seems like the best, then by all means use it.

One thing that you might need to watch out for is exception safety.
Constructors can and often do throw exceptions. You would want to
guarantee that for any object you've constructed with placement new, you
also call its destructor. In the example above, that might involve
doing something like:

try
{
for (count = 0; count < N; ++count)
new (p+count) Point ;
}
catch (...)
{
for (; count; --count)
p[count-1].~Point() ;
throw ;
}

This safely destructs any object that happens to get constructed, even
if an exception is thrown in the constructor. There is an additional
concern that the destructor could throw an exception, but typically the
approach taken is to assume that destructors don't throw (this is the
approach taken by the standard library).

I will consider the exception safety (Though I wonder if it can throw
any bad_alloc as it is not allocating any memory, rather the memory
allocation routine need to throw exception on failure).
My problem is related to computational geometry, and supposed to run
in mobile. Thus memory, cache, program size, even the support of stl
feature is important.
The basic is a set of characters in a page, and each character
contains points.
Processing relates points between two characters. Thus instead easy
approach like, page contains a vecctor of char, and char contains a
array of points, I want it in this way (and my boss also.... stanford
cs prof :) ). It is not general commercial type of program, rather a
research in computational geometry. Even sometimes, I want to limit stl
usage, as the support for template is poor and the executable memory
may be as less as 200k.
Also I may not get as optimized compiles as one gets for pentium class
processor.
This imlementation looks easier to digest and easier to understand
what is actually happening.
Why it is not adviced? where is the actual problem? doesn't stl
vector use placement new? is it nonportable feature? (I assume I will
make a correct implementation of course)

The default constructor works fine.

--
I am implementing it .... will check performance difference .
One more thing, any way to resize the buffer pointed by p? say I want
to increase size N? any c realloc equivalent? i.e check if it can be
resized in place. otherwise copy it in new location....

Resizing will be very rare, almost zero, unlike stl vector wich is
made for resizing.
abir
 
A

Alan Johnson

toton said:
In general you should try to avoid it, because you are taking into your
own hands something the compiler normally will do for you. This means
that you've introduced more opportunities for errors, inefficiencies, etc.

That said, you are the one that best knows the problem you are trying to
solve, and whether a solution that decouples allocation from
initialization is appropriate. If after considering all the possible
designs, it still seems like the best, then by all means use it.

One thing that you might need to watch out for is exception safety.
Constructors can and often do throw exceptions. You would want to
guarantee that for any object you've constructed with placement new, you
also call its destructor. In the example above, that might involve
doing something like:

try
{
for (count = 0; count < N; ++count)
new (p+count) Point ;
}
catch (...)
{
for (; count; --count)
p[count-1].~Point() ;
throw ;
}

This safely destructs any object that happens to get constructed, even
if an exception is thrown in the constructor. There is an additional
concern that the destructor could throw an exception, but typically the
approach taken is to assume that destructors don't throw (this is the
approach taken by the standard library).

I will consider the exception safety (Though I wonder if it can throw
any bad_alloc as it is not allocating any memory, rather the memory
allocation routine need to throw exception on failure).

Placement new should only throw if the constructor throws (I'm not 100%
sure about this but I can't see any reason why it would not be true).
The call to operator new, however, can throw std::bad_alloc.
My problem is related to computational geometry, and supposed to run
in mobile. Thus memory, cache, program size, even the support of stl
feature is important.
The basic is a set of characters in a page, and each character
contains points.
Processing relates points between two characters. Thus instead easy
approach like, page contains a vecctor of char, and char contains a
array of points, I want it in this way (and my boss also.... stanford
cs prof :) ).

Leonidas Guibas, by chance? I recently took (did somewhat poorly :-/ )
his computational geometry class.

Why it is not adviced? where is the actual problem? doesn't stl
vector use placement new? is it nonportable feature? (I assume I will
make a correct implementation of course)

It is portable. The only advice against it is that you are taking
control over something that the compiler and/or standard library
normally handles for you (and usually handles both correctly and
efficiently). It is not wrong to handle such things yourself, but
unless you gain significantly from doing so, it is safer and easier to
let the compiler/standard library do it.
I am implementing it .... will check performance difference .
One more thing, any way to resize the buffer pointed by p? say I want
to increase size N? any c realloc equivalent? i.e check if it can be
resized in place. otherwise copy it in new location....

Resizing will be very rare, almost zero, unlike stl vector wich is
made for resizing.
abir

Speaking generically, resizing doesn't make a whole lot of sense in C++.
What happens if the resize requires moving objects? If the objects
are of non-POD type then you need to use their copy constructor, which
means you can only use it with types that are CopyContructible. At that
point you might as well use std::vector as you are basically
functionally equivalent to it.

Depending on how exotic you really want to get, you could overload
operator new and operator delete to use the C-style memory allocation,
and then add a custom operator new for resizing, maybe something like:

#include <cstddef> // for size_t
#include <cstdlib>
#include <new>

void * operator new(std::size_t sz) throw (std::bad_alloc)
{
void * ptr = std::malloc(sz) ;
if (!ptr)
throw std::bad_alloc() ;
return ptr ;
}

// The bool parameter is there just to distinguish this from placement new.
void * operator new(std::size_t sz, void * old, bool) throw (std::bad_alloc)
{
void * ptr = std::realloc(old, sz) ;
if (!ptr)
throw std::bad_alloc() ;
return ptr ;
}

void operator delete(void * ptr) throw()
{
// Deleting 0 is allowed by the standard.
if (ptr)
std::free(ptr) ;
}

If you are going to go to that much trouble, though, you might as well
just use malloc and free directly.
 
T

toton

Alan said:
toton said:
In general you should try to avoid it, because you are taking into your
own hands something the compiler normally will do for you. This means
that you've introduced more opportunities for errors, inefficiencies, etc.

That said, you are the one that best knows the problem you are trying to
solve, and whether a solution that decouples allocation from
initialization is appropriate. If after considering all the possible
designs, it still seems like the best, then by all means use it.

One thing that you might need to watch out for is exception safety.
Constructors can and often do throw exceptions. You would want to
guarantee that for any object you've constructed with placement new, you
also call its destructor. In the example above, that might involve
doing something like:

try
{
for (count = 0; count < N; ++count)
new (p+count) Point ;
}
catch (...)
{
for (; count; --count)
p[count-1].~Point() ;
throw ;
}

This safely destructs any object that happens to get constructed, even
if an exception is thrown in the constructor. There is an additional
concern that the destructor could throw an exception, but typically the
approach taken is to assume that destructors don't throw (this is the
approach taken by the standard library).

I will consider the exception safety (Though I wonder if it can throw
any bad_alloc as it is not allocating any memory, rather the memory
allocation routine need to throw exception on failure).

Placement new should only throw if the constructor throws (I'm not 100%
sure about this but I can't see any reason why it would not be true).
The call to operator new, however, can throw std::bad_alloc.
My problem is related to computational geometry, and supposed to run
in mobile. Thus memory, cache, program size, even the support of stl
feature is important.
The basic is a set of characters in a page, and each character
contains points.
Processing relates points between two characters. Thus instead easy
approach like, page contains a vecctor of char, and char contains a
array of points, I want it in this way (and my boss also.... stanford
cs prof :) ).

Leonidas Guibas, by chance? I recently took (did somewhat poorly :-/ )
his computational geometry class.
Nop! Thomas O. Binford .... emeritus cs stanford ... very strict about
memory... dont want to waste a single bit !!!.... just joking ... :)
 
T

toton

Frederick said:
Yes, interesting....
boost is doing nearly same thing as proposed by Johnson in this post.
actually the whole implementation is little different than C++ RAII
feature... Rather things look like Java array feature, where array
doesn't initializes the object the array contains.
But Java has advantage, that its array holds reference, not the object
itself. In C++ this looks same as vector<Point*> kind of thing. But
requirement is to hold the object itself inside the container, and RAII
fails there. Sometimes people may need it... (I feel that for container
classes the memory allocation and object initialization need to be
different, and when the contained object is known at prior , i.e they
are not to be subclassed, storing by value is a better solution, as
most of the time container classes store little struct in huge no
rather that big objects in small jo).
Anyone sees advantage with it?
abir
 
M

Marcus Kwok

toton said:
In C++ when I initialize an array it, also initializes the class that
it contains, which calls the default constructor. However, I want to
initialize the array only (i.e reserve the space) and use my specific
constructor to initialize the class. How to do it without using malloc?

How about something like this:

#include <iostream>
#include <ostream>
#include <vector>
#include <algorithm>
#include <iterator>

class Point {
public:
Point(int x, int y) : x_(x), y_(y) { }
friend std::eek:stream& operator<<(std::eek:stream& o, const Point& p);

private:
int x_;
int y_;
};

std::eek:stream& operator<<(std::eek:stream& o, const Point& p)
{
return o << '(' << p.x_ << ", " << p.y_ << ')';
}



int main()
{
std::vector<const Point> v;
v.reserve(3);

v.push_back(Point(1, 1));
v.push_back(Point(2, 3));
v.push_back(Point(42, 100));

const std::vector<const Point> use_this(v.begin(), v.end());

std::copy(use_this.begin(),
use_this.end(),
std::eek:stream_iterator<Point>(std::cout, "\n"));
}
 
M

Marcus Kwok

Marcus Kwok said:
How about something like this:

#include <iostream>
#include <ostream>
#include <vector>
#include <algorithm>
#include <iterator>

class Point {
public:
Point(int x, int y) : x_(x), y_(y) { }
friend std::eek:stream& operator<<(std::eek:stream& o, const Point& p);

private:
int x_;
int y_;
};

std::eek:stream& operator<<(std::eek:stream& o, const Point& p)
{
return o << '(' << p.x_ << ", " << p.y_ << ')';
}



int main()
{
std::vector<const Point> v;
v.reserve(3);

v.push_back(Point(1, 1));
v.push_back(Point(2, 3));
v.push_back(Point(42, 100));

const std::vector<const Point> use_this(v.begin(), v.end());

Maybe as an alternative (so you don't have to create two vectors), use

const std::vector<const Point>& use_this = v;

instead.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,152
Latest member
LorettaGur
Top