Lingyun,

I strongly recommend you to read your std::vector implementation's
source code and debug it to understand its behavior.

Vector starts with 0 or room for few elements. When you push_back, it
checks for available space in its internal block. If requested size is
greater than current capacity, vector will want to grow to accomodate
new items. Because it can't realloc, it will allocate a completely new
buffer, which will be greater than or equal to new size (new size is
greater than the current size).

For instance:
std::vector<int> v;
// push_back 6 items...
'v' has 6 items. that is, 6 * sizeof(int) memory for storage.
if you want to insert 7th item, vector needs to grow (how much it
grows depends on implementation; e.g. Visual C++'s, Dinkumware's
library says "try to grow by 50%"), because there is no room to place
7th item.

To perform this operation, library allocates a new block of memory
that can accomodate *at least* 7 items *before* destroying existing
block. Dinkumware's library expands by 50%, so it may grow by 3 items'
size (assuming it had 6 items), which makes new capacity 9 items (6 +
(6 * 0.5)).

This sums up:
6 existing items
9 new size
+------
15 items.
After new block is allocated successfully, vector copies its existing
objects (6 objects) onto new buffer (which can hold 9 items). After
copy succeeds, vector destroys previous buffer (6 items), then you
have a vector whose capacity is sizeof(int) * 9. Until 9th item,
vector will not need to reallocate memory.

2009/4/15 Lingyun Yu <lingyun.yu...@gmail.com>:
> Hi, Ismail,
>
> I don't understand how the "expanding" happen?
> I read all dataset into an array of P, then when it expands? and why?
> and what's old array?
>
> On Tue, Apr 14, 2009 at 2:27 PM, Ismail Pazarbasi <pazarb...@gmail.com>
> wrote:
>>
>> Hi Lingyun,
>>
>> std::bad_alloc is thrown when operator new cannot allocate memory,
>> which indicates there is not enough memory. You may reserve your array
>> before hand, as Paul mentioned, but it may throw as well. This could
>> reduce, if nothing, copy operations. It may also prevent exception,
>> because when expanding, std::vector will have two large copies at the
>> same time. That is:
>> e.g. old array length was 1500000
>> expand by 500000
>> While allocating 2000000 elements, previous 1500000 elements will also
>> be alive/allocated, that requires room for 3500000 elements in total.
>> Resize may reduce this cost to 2000000 only, because vector will not
>> have to expand afterwards (i.e. during push_back), which requires a
>> copy operation. Note that C++ standard allocator doesn't do realloc().
>> Instead, vector will allocate a block of  N * sizeof(T) items (or
>> little more), copy existing block into new one, then free existing
>> block.
>>
>> // instantiate vertices normally
>> vertices = new osg::Vec3Array;
>>
>> // if number of parts is greater than 1000,
>> // reserve your items before.
>> if (NumPart > 1000)
>> {
>>   try
>>   {
>>      vertices->reserve(NumPart);
>>   }
>>   catch (std::bad_alloc& e)
>>   {
>>       // handle exception here; log and return error from this function.
>>       // alternatively, you can rethrow here, and catch in caller.
>>   }
>> }
>>
>> // wrap your push_back calls in a try-catch block
>> try
>> {
>>   vertices->push_back(...);
>> }
>> catch (std::exception&)
>> {
>> }
>>
>> To be on the safe side, handle your exceptions and wrap your pointers
>> in a smart pointer class. If an exception is thrown and you
>> rethrow/return from function, you need to delete your Geode, Group and
>> other objects. You may get all these for free, if you use a smart
>> pointer (osg::ref_ptr<T>, in this case, as osg::Node's destructor is
>> protected, IIRC, which prevents it to be "delete"d externally, but
>> only when its ref count reaches 0).
>>
>> HTH
>> Ismail
>>
>> 2009/4/13 Paul Martz <pma...@skew-matrix.com>:
>> > Hi Lingyun Yu --
>> > You don't have a variable named 'galaxy' defined, so the
>> > "addDrawable(galaxy)" is suspicious.
>> >
>> > I'd so a resize on the vertex and color arrays, rather than a push_back,
>> > for
>> > efficiency reasons.
>> >
>> > I don't think numParts>1000000 should cause any problems. OpenGL doesn
>> > not
>> > place an upper limit on the number of primitives you can render with a
>> > single glDrawArrays call.
>> >
>> > I don't really see anything that would cause a crash so I guess you
>> > should
>> > use a debugger and look at the call stack, like you would any other
>> > crash.
>> >
>> > Paul Martz
>> > Skew Matrix Software LLC
>> > http://www.skew-matrix.com
>> > +1 303 859 9466
>> >
>> >
>> > -----Original Message-----
>> > From: osg-users-boun...@lists.openscenegraph.org
>> > [mailto:osg-users-boun...@lists.openscenegraph.org] On Behalf Of Sent:
>> > Monday, April 13, 2009 9:27 AM
>> > To: osg-users@lists.openscenegraph.org
>> > Subject: [osg-users] Problem of points showing
>> >
>> > Hi, everybody,
>> >
>> > I met a problem when I want to show huge amount of points, as you can
>> > see
>> > the code below, if my NumPart is 1000000, no problem, it shows points
>> > properly. But if the NumPart is 2000000, then it shows a lot of lines.
>> > If
>> > NumPart is even bigger, the program complained like this:Microsoft C++
>> > exception: std::bad_alloc at memory location 0x0030e898.
>> >
>> > I don't know that's because the dataset is too big or not? because while
>> > it
>> > shows not so many points, everything goes well.
>> >
>> > By the way, the data in P array are all right.
>> >
>> > osg::Geode *makeGalaxy()
>> > {
>> >     osg::Geode *geode = new osg::Geode();
>> >     osg::Geometry *geometry= new osg::Geometry();
>> >     osg::Vec3Array *vertices = new osg::Vec3Array();
>> >     osg::Vec4Array *colors = new osg::Vec4Array();
>> >     osg::Vec4 ini(1,0.1,0.55,1);
>> >     osg::Vec4 fin(0,1,0,1);
>> >
>> >     for (int i = 1; i <= NumPart; i++)
>> >         {
>> >
>> > vertices->push_back(osg::Vec3(P[i].Pos[0],P[i].Pos[1],P[i].Pos[2]));
>> >         colors->push_back(ini+(fin-ini)*(i*1/NumPart));
>> >         }
>> >     geometry->setVertexArray(vertices);
>> >     geometry->setColorArray(colors);
>> >     geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
>> >     geometry->addPrimitiveSet(new
>> > osg::DrawArrays(osg::PrimitiveSet::POINTS,
>> > 0, NumPart));
>> >     geode->addDrawable(galaxy);
>> >         return geode;
>> > }
>> >
>> > ...
>> >
>> > Thank you.
>> >
>> > ------------------
>> > Read this topic online here:
>> > http://forum.openscenegraph.org/viewtopic.php?p=10166#10166
>> >
>> >
>> >
>> >
>> >
>> > _______________________________________________
>> > osg-users mailing list
>> > osg-users@lists.openscenegraph.org
>> >
>> > http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>> >
>> > _______________________________________________
>> > osg-users mailing list
>> > osg-users@lists.openscenegraph.org
>> >
>> > http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>> >
>> >
>> _______________________________________________
>> osg-users mailing list
>> osg-users@lists.openscenegraph.org
>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
>
>
> --
> Cheers,
> Yun
>
> _______________________________________________
> osg-users mailing list
> osg-users@lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
>
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to