1. Environment

– windows xp
– gcc-4.4
– boost-1.43

2. auto_ptr

A smart pointer is an abstract data type that simulates a pointer while providing additional features, such as automatic garbage collection or bounds checking. There’s auto_ptr in C++03 library for general use. But it’s not so easy to deal with it. You may encounter pitfalls or limitations. The main drawback of auto_ptr is that it has the transfer-of-ownership semantic. I just walk through it. Please read comments in code carefully:

3. unique_ptr

To resolve the drawbacks, C++0x deprecates usage of auto_ptr, and unique_ptr is the replacement. unique_ptr makes use of a new C++ langauge feature called rvalue reference which is similar to our current (left) reference (&), but spelled (&&). GCC implemented this feature in 4.3, but unique_ptr is only available begin from 4.4.

What is rvalue?

rvalues are temporaries that evaporate at the end of the full-expression in which they live (“at the semicolon”). For example, 1729, x + y, std::string(“meow”), and x++ are all rvalues.

While, lvalues name objects that persist beyond a single expression. For example, obj, *ptr, ptr[index], and ++x are all lvalues.

NOTE: It’s important to remember: lvalueness versus rvalueness is a property of expressions, not of objects.

We may have another whole post to address the rvalue feature. Now, let’s take a look of the basic usage. Please carefully reading the comments:

One can ONLY make a copy of an rvalue unique_ptr. This confirms no ownership issues occur like that of auto_ptr. Since temporary values cannot be referenced after the current expression, it is impossible for two unique_ptr to refer to a same pointer. You may also noticed the move function. We will also discuss it in a later post.

Some more snippet:

unique_ptr can hold pointers to an array. unique_ptr defines deleters to free memory of its internal pointer. There are pre-defined default_deleter using delete and delete[](array) for general deallocation. You can also define your customized ones. In addition, a void type can be used.

NOTE: To compile the code, you must specify the -std=c++0x flag.

4. shared_ptr

A shared_ptr is used to represent shared ownership; that is, when two pieces of code needs access to some data but neither has exclusive ownership (in the sense of being responsible for destroying the object). A shared_ptr is a kind of counted pointer where the object pointed to is deleted when the use count goes to zero.

Following snippet shows the use count changes when using shared_ptr. The use count changes from 0 to 3, then changes back to 0:

Snippets showing pointer type conversion:

The void type can be used directly without a custom deleter, which is required in unique_ptr. Actually, shared_ptr has already save the exact type info in its constructor. Refer to source code for details :). And static_pointer_cast function is used to convert between pointer types.

Unlike auto_ptr, Since shared_ptr can be shared, it can be used in STL containers:

NOTE: shared_ptr is available in both TR1 and Boost library. You can use either of them, for their interfaces are compatible. In addition, there are dual C++0x and TR1 implementation. The TR1 implementation is considered relatively stable, so is unlikely to change unless bug fixes require it.

5. weak_ptr

weak_ptr objects are used for breaking cycles in data structures. See snippet:

If we use uncomment to use shared_ptr, head is not freed since there still one reference to it when exiting the function. By using weak_ptr, this code works fine.

6. scoped_ptr

scoped_ptr template is a simple solution for simple needs. It supplies a basic “resource acquisition is initialization” facility, without shared-ownership or transfer-of-ownership semantics.

This class is only available in Boost. Since unique_ptr is already there in C++0x, this class may be thought as redundant. Snippet is also simple:

Complete and updated code can be found on google code host here. I use conditional compilation to swith usage between TR1 and Boost implementation in code. Hope you find it useful.

Let clarify some concepts first. What is C++0x? Wikipedia gives some overview here:

C++0x is intended to replace the existing C++ standard, ISO/IEC 14882, which was published in 1998 and updated in 2003. These predecessors are informally but commonly known as C++98 and C++03. The new standard will include several additions to the core language and will extend the C++ standard library, incorporating most of the C++ Technical Report 1 (TR1) libraries — with the exception of the library of mathematical special functions.

Then why it is called C++0x? As Bjarne Stroustrup addressed here:

The aim is for the ‘x’ in C++0x to become ‘9’: C++09, rather than (say) C++0xA (hexadecimal :-).

You may also noticed TR1, also refer here in Wikipedia:

C++ Technical Report 1 (TR1) is the common name for ISO/IEC TR 19768, C++ Library Extensions, which is a document proposing additions to the C++ standard library. The additions include regular expressions, smart pointers, hash tables, and random number generators. TR1 is not a standard itself, but rather a draft document. However, most of its proposals are likely to become part of the next official standard.

You got the relationship? C++0x is the standard adding features to both language and standard library. A large set of TR1 libraries and some additional libraries. For instance, unique_ptr is not defined in TR1, but is included in C++0x.

As of 12 August 2011, the C++0x specification has been approved by the ISO.

Another notable concept is the Boost library. It can be regarded as a portable, easy-to-use extension to the current C++03 standard library. And some libraries like smart pointers, regular expressions have already been included in TR1. You can find license headers regarding the donation of the boost code in libstdc++ source files. While in TR2, some more boost code are to be involved.

TR1 libraries can be accessed using std::tr1 namespace. More info on Wikipedia here:

Various full and partial implementations of TR1 are currently available using the namespace std::tr1. For C++0x they will be moved to namespace std. However, as TR1 features are brought into the C++0x standard library, they are upgraded where appropriate with C++0x language features that were not available in the initial TR1 version. Also, they may be enhanced with features that were possible under C++03, but were not part of the original TR1 specification.

The committee intends to create a second technical report (called TR2) after the standardization of C++0x is complete. Library proposals which are not ready in time for C++0x will be put into TR2 or further technical reports.

The article seems to be a bit too long so far, I decide to give my snippets in a later post.

Generally, BIOS info can be found by dmidecode utility(run as root), like:

Here, I retrieve it by using libhd library provided in hwinfo utility:

Since the DVD size of CentOS 5.x is largely increased(1.7G for 3.x, 2.3G for 4.x, while 4.0G for 5.x), I decided to use the CD approach. I downloaded the first CD image from one of its mirror site: http://mirrors.163.com/centos/5.6/isos/i386/.

Now, follow the official FAQ here:

– You can do a minimal install that just requires the first CD by performing the following two steps during the installation:
** During the category/task selection, deselect all package categories, and choose the “Customize now” option at the bottom of screen.
** During the customized package selection, deselect everything ( including the Base group ).
– There are reports that more than CD 1 is required in the following case:
** If you use some software raid options (this will also require CD 2 and 5)
** If you use encrypted filesystems
– When the anaconda installer notes that additional disks will be required but you desire a one CD install, the quick answer is one or more of the following approaches:
** Trim back and do a minimal install. Then once the install is up and running, pull in more packages with yum and add more options later.
– If you want to avoid using more than one CD but want to install more than just the minimal set of packages, you could also consider doing a network installation. A network installation ISO (called boot.iso) is available from the 5/os/<arch>/images/ directory on CentOS mirrors.
– This latter mode of installation, however, is only really reliable via a LAN (an Intranet installation) and not via the Internet.

From my practice, you MUST follow the de-selection order. Otherwise, it will still require other CDs. The actual installation lasts for about 1 minutes(installation of *.rpm files). After reboot, the system gives you a minimum installation with only text mode support. Now login with your root account, and make sure your network is ready. Additional components shall be installed manually using yum:

NOTE: All group names are case-sensitive.

Actually, if only “X Window System” are passed to yum, you will get a simple GUI with an xterm and an xclock after running “startx” command.

You may want to take coffee during the process. For me, about 350M contents were downloaded. Reboot when finished and add “single” option to enter single mode in GRUB menu.

Since the first CD does not install GUI contents, so the runlevel is set to 3(text mode) by default after installation. We should switch it to 5(GUI mode) by editing /etc/inittab file, Find the line and change the middle value from 3 to 5:

Now, we want to start the “firstboot” configuration utility to simplify our user account creation and other initial configurations. Check /etc/sysconfig/firstboot file, and make sure the value is set to “YES” like:

If the value is “NO”, the “firstboot” utility is skipped and GDM is displayed directly. When all have been done, issue the “exit” command to return to the normal startup process. This time, the “firstboot” wizard should show.

Here is the GDM screenshot after all above steps:

centos5_gdm

PS:

In 6.x, CentOS provides LiveCD and LiveDVD that can be used also for installation. But in 5.x, they can only be used for trial experience.

In 4.x/3.x, the openoffice suite is outdated, I suggest to not install them. I also suggest to remove redundant kernels:

There’s 4.9 release but no 4.9 *.iso images. The readme.txt says:

– The upstream provider did not respin media for the 4.9 release and therefore the CentOS project will also not respin our install media.
– Installs moving forward will be off the 4.8 media and an upgrade will move you from version 4.8 to version 4.9.
– We do this to maintain compatibility with 3rd party kernel drivers which are designed to be installed as part of the installation process.

Run “yum update” to update from 4.8 to 4.9. For me, about 300M contents were downloaded.

In 3.x release, I suggest to select “Kernel Development” group during installation. The 2.4.x kernel needs its source to compile kernel modules(like virtual machine addons).

I used mencoder utility to convert my video files. But it was compiled without libfaac. So if you specify AAC encoding, an error occurs. Details and solutions can be found here. I just added the Medibuntu repository as described:

NOTE: ffmpeg utility in Lucid release does not support *.rm/*.rmvb yet.

Then install mencoder and codecs:

Now you can convert videos. Here’s a sample to convert a *.rmvb(848×480) to a *.mp4(320×240):

Modify fps/codec/bitrate values as you wish. The aglobal & vglobal options seem to be essential for iPod.

In order to keep video aspect after scaling, the output file should be 360×204. we use the -vf-add filter to add black band to the top and bottom of it. Other command line options, please refer to its manpage.

Lastly, install gtkpod to import your *.mp4 files.

Updated Mar 27, 2012: The above command line is for iPod Nano. For high quality H264 encoding used in iPod Touch or iPhone, run: