Smart pointers in OSG

Source: Internet
Author: User
Tags addchild

In OpenSceneGraph, the concept of smart pointers (smart pointer) refers to the template of a class that builds on a particular type of object (that is, the referenced class and its derived classes) and provides its own management mode. To avoid the consequences of wasting part of the memory space, which is known as a memory leak error, since the user created the object instance using the new operator and did not release the object in time with the delete operator.

Because most of the classes related to scene graphics in OSG derive from the referenced class, OSG uses a lot of smart pointers to manage the scene graph nodes. The use of smart pointers provides a mechanism for users to automatically release memory, that is, each node in the scene graph is associated with a memory counter, and when the counter count is reduced to 0 o'clock, the object is automatically freed. If the user wants to release the entire scene graph node, then only need to delete the root node, all the branches below the root node will be automatically deleted, do not worry about memory leaks.

To use OSG Smart pointers, you need to meet the following two conditions:

1. The user's class must derive from the referenced class so that it can use the memory counter associated with itself;

2, use the smart pointer template Osg::ref_ptr<class t> to define an instance of the class, when the user uses the template to define the instance, the memory counter is enabled and added one; Similarly, when the ref_ptr template exceeds its life span, the memory counter of the class instance is reduced by one, The object is automatically freed if it is reduced to zero.

In addition, to use smart pointers, the following header files should be referenced in the program:

#include <osg/ref_ptr>

An example of using smart pointers is as follows:

voidExamplefunc () {osg::ref_ptr<osg::Group> root =NewOsg::group; Osg::ref_ptr<osg::Geode> Node1 =NewOsg::geode; Osg::ref_ptr<osg::Geometry> Geo1 =NewOsg::geometry; printf ("%d,%d,%d\n", Root->referencecount (), Node1->referencecount (), geo1->Referencecount ()); Root->addchild (Node1.Get()); Node1->adddrawable (geo1.Get()); printf ("%d,%d,%d\n", Root->referencecount (), Node1->referencecount (), geo1->Referencecount ());}

The example itself does not make sense, but it can be used to understand the flow of smart pointers.

Before reading this example, first look at the main members and operators related to the REF_PTR and referenced classes:

Referenced class

void ref ()

This common function causes the memory counter value of the referenced class instance to be incremented by one.

void unref ()

This common function causes the memory counter value of the referenced class instance to be reduced by one, and if the counter value is zero, it automatically attempts to delete the instance of the class, freeing the corresponding memory.

int Referencecount ()

Returns the numeric value of the current memory counter.

Ref_ptrref_ptr ()

constructor, but it does nothing. The use cases are:

Osg::ref_ptr<osg::node> node1;ref_ptr (T* ptr)

Constructor, and allocates a new memory space for its objects, plus one for the object's memory counter value. The use cases are:

osg::ref_ptr<osg::node>new  osg::node;ref_ptr (const ref_ptr& RP)

constructor, its object will point to an existing smart pointer object, and the object's memory counter value is incremented by one. The use cases are:

osg::ref_ptr<osg::node> node2 = node1; ~ref_ptr ()

destructor, minus one of the memory counter values of the object at execution time.

operator = (const ref_ptr& RP)

Overloaded assignment operators, which use the following:

Node2 = Node1;

Point Node2 to Node1 and add a memory counter value of Node2 (that is, Node1).

operator = (t* ptr)

Overloaded assignment operators, which use the following:

new Osg::node;

Point Node2 to an instance of a class and add the Node2 memory counter value one at a time.

operator Const

Returns the value of the class instance. For example:

osg::ref_ptr<osg::node>new Osg::node;

Then *node1 represents Osg::node

operator Const

Returns an instance of the class. For example:

new Osg::node;

Then Node1-> to denote (osg::node*)->

Get Const

Returns an instance of the class. For example:

new Osg::node;

Then Node1.get () represents osg::node*

bool Valid ()

A flag that returns whether the pointer is valid.

void Swap (ref_ptr& RP)

Swaps the content pointed to by the current pointer to the data entered by the user. The use cases are:

// swap the position of two pointers

Then look at the example program, which mainly accomplishes this function:

1. Create a new two node root and Node1, and a geometry geo1;

2, call the smart pointer get method, the Node1 as the root of the child node join (addChild);

3. Call the smart pointer's Get method to add Geo1 as Node1 's drawing data (adddrawable).

In addition, the program calls the Referencecount method to observe the value of the memory counter.

Call this child function in the main function, compile and run, and observe the results as shown:

1, 1, 1

1, 2, 2

It can be seen that when nodes and geometries are created for the first time, their memory counters are automatically incremented by one, and the memory counters of the two are added again by adding node1 as child nodes and adding geo1 as graphical elements.

Use the new operator to add one to the memory counter because the ref () method is executed in the Ref_ptr constructor. This method automatically adds one to the memory counter of the current instance.

The function Addchild and adddrawable will cause the memory counter to add one because the program will add Node1 or geo1 to a ref_ptr vector table. Referring to the source code, the vector table used to hold the child nodes is nodelist, which is defined as:

typedef std::vector< ref_ptr<node> > NodeList;

The vector table used to hold geometry geometry data is drawablelist, which is defined as:

typedef std::vector< ref_ptr<drawable> > drawablelist;

When executing functions addchild and adddrawable, using the Push_back method of the Vector table template, the data with the smart pointer is pressed into the vector table, this step will automatically add a memory counter. The specific implementation process can be found in the VC directory of the vector header file, which has the following sentence segment:

= _val;

For NodeList, the _ty in the above represents Ref_ptr<node>, while _val is the data of the compression vector table, so there are:

ref_ptr<node> _tmp = Node1.get ();

Referring to the form of the second constructor in Ref_ptr, the system calls the ref () function, which adds one more to the memory counter, and obviously this action has an impact on Node1.

Similarly, when executing the pop_back or erase function of a vector table, the memory counter is automatically reduced by a call to the destructor of the ref_ptr. Perform functions removechild and removedrawable to achieve this effect.

Looking at a common situation, the code is as follows:

 for (int0; i++) {osg::nodenew  osg::node; ...}

In general, using the new operator in a loop opens up the memory space and, if not released in a timely manner, creates a memory leak. For the above program segment, if you open the Task manager at run time, you can see that the memory value of the program is rising and, if unchecked, may even cause the computer to crash.

Now rewrite the statement line with the new operator in the program segment as follows:

// osg::node* Node = new Osg::node; new Osg::node;

Run the program again, you can see that the memory growth phenomenon disappears, smart pointers here play a role that can not be ignored. The process of analyzing this section of the program is visible:

1, after entering the loop, first allocates a new memory area for node, and the memory counter automatically adds one;

2, the execution of the rest of the code, if you do not use Addchild node, and so on, then the value of the counter is always 1;

3. Reach the end of the For Loop, at which time the life cycle of the temporary variable has ended, then execute ~ref_ptr (), where the value of the counter is automatically unref () minus one, then the value of the counter is 0, and the system automatically frees the memory area.

4, the new cycle begins, when the original memory area has been released, there is no memory leak situation.

In summary, the use of smart pointer ref_ptr to wrap the user's node class, geometry classes and other data, can be effectively memory management, to a large extent, to avoid the occurrence of memory leakage phenomenon. In the use of smart pointers, you should also pay attention to the following points:

1. The Application object of the smart pointer template must be derived from the referenced class, otherwise the template will not be available. For example:

Osg::ref_ptr<osg::vec3> v;

Such a declaration cannot be compiled because the VEC3 class is not derived from the referenced class and therefore does not have member functions such as ref () and unref () and cannot be associated with a counter.

2. You cannot delete an object that applies a smart pointer directly by using the delete operator. In fact, such statements can not be compiled through, read the source code of the referenced class to find that the referenced class destructor ~referenced () is a protection function (protected type), directly using the delete operator call it is not allowed.

3. Do not arbitrarily use the ref () and unref () functions to change the value of the memory counter. Since both functions are public functions, such operations do not cause errors in the compilation, but if the value of the memory counter is reduced to zero when the program is running, so that its object is freed, then all operations against this object may result in a program crash. Such changes will never occur in normal use, so try not to use ref () and unref () to change the value of the memory counter directly unless the user has a special need.

4. In OSG, it is also possible to use a form such as Osg::node * Node instead of a smart pointer. However, in large programs, you should use smart pointers as much as possible to manage memory. In addition, sometimes there is no unified use of REF_PTR, the program may also have problems. Like this example:

osg::group* Examplefunc () {osg::ref_ptrnew  Osg::group;  Osg::ref_ptrnew  Osg::geode; Root->addchild (node1.   Get()); ... return root->get();} int Main (intChar* * argv) {... osg::node* a = Examplefunc ()->getchild (  C14>0); ...}

Because the life cycle of the ref_ptr ends at the end of the function, the group pointers that are returned when the function returns are actually freed, so that the program compiles and links are not associated with errors, but errors are encountered at run time, and this error is often difficult to detect. In order to solve the problem, the uniform modification of the program to Ref_ptr is named as follows:

Osg::ref_ptr<osg::group> Examplefunc () {osg::ref_ptrnew  Osg::group;  Osg::ref_ptrnew  Osg::geode; Root->addchild (node1.   Get()); ... return Root;} int Main (intChar* * argv) {... ref_ptr<osg::Node> a = Examplefunc ()-  >getchild (0); ...}

You can run it through. When the function returns, REF_PTR will add the value of the memory counter again to ensure that the returned data is valid, and the main function can still be left to the smart pointer for memory management.

Smart pointers in OSG

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.