青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

鍵盤上的舞者

My Email: marckywu@gmail.com
隨筆 - 19, 文章 - 0, 評論 - 3, 引用 - 0
數據加載中……

Allocating Arrays Using Placement new (zz)

       An additional version of operator new enables you to construct an object or an array of objects at a predetermined memory position. This version is called placement new and has many useful applications, including building a custom-made memory pool or a garbage collector. Additionally, it can be used in mission-critical applications because there's no danger of allocation failure; the memory that's used by placement new has already been allocated. Placement new is also faster because the construction of an object on a preallocated buffer takes less time.

You already know how to use placement new to allocate a single object on a predetermined memory address. However, some programming tasks require the allocation of arrays on a predetermined memory address. Here's how you do it.

Placement new Overview

Mobile devices, embedded systems and custom garbage collectors are only a few instances of programming environments that may require placement new allocation of arrays. Before I discuss the details of such array allocations, let's remind ourselves briefly how scalar (i.e. non-array) placement new works.

The scalar version of placement new takes a user-supplied address on which it constructs a single object. Unlike the ordinary version of the new operator, placement new doesn't allocate storage for the object; it merely constructs the object on the memory address you provide:

#include <new> //required for using placement new
class Widget {
public:
    Widget();
    
virtual ~Widget
    
virtual void Draw();
};
char* buf=new char [sizeof (Widget)];//preallocate
Widget* widget= new(buf) Widget; //construct Widget on buf
widget->Draw(); //use Widget

To destroy widget you first have to invoke its destructor explicitly:

widget->~Widget(); //explicit destructor invocation

Next, reclaim the raw memory like this:

delete[] buf;

Array Allocation

Allocating arrays with placement new follows the same steps more or less, but you have to pay attention to additional nuances. Here is a step-by-step guide:

First, allocate a buffer large enough to hold an array of the desired type:

const int ARRSIZE = 15;
char * buf= new [sizeof(Widget)*ARRSIZE];

Don't be tempted to calculate the size manually; always use sizeof to ensure that the buffer is properly aligned and has the right size.

Next, construct an array of ARRSIZE objects on the buffer using placement new[] :

Widget* widgets=new(buf) Widget[ARRSIZE];//construct an array

You can now use the allocated array as usual:

for (int i=0; i<ARRSIZE; i++)
{
 widgets[i].Draw();
}
Make sure that your target class -- Widget in this example -- has a public default constructor. Otherwise, it would be impossible to create arrays thereof.

Destroying the Array

To destroy such an array allocated by placement new you have to call the destructor for each element explicitly:

int i=ARRSIZE;
while (i)
    widgets[
--i].~Widget();

The while -loop uses a descending order to preserve the canonical destruction order of C++ -- the object that was constructed last must be destroyed first. To comply with this requirement, the element with the highest index is destroyed first.

Finally, you release the raw memory on which the array resided by calling delete[] :

delete[] buf;

Performance Tuning

The array placement new has a potential performance problem: it initializes every element in the array unconditionally. If your app deals with large arrays, this isn't the most efficient way. In some apps only a portion of the array is actually used, and in other apps the elements are assigned a different value immediately after their construction. In these cases, you want to postpone, or even completely avoid, the automatic initialization of array elements. To avoid the initialization of placement new arrays, follow the following steps:

As before, begin with an allocation of a raw buffer with the appropriate size. This time however, use the global operator new instead of the new operator:

Widget * warr=
static_cast
<Widget*> (::operator new ( sizeof(Widget)* ARRSIZE));

The global operator new , very much like C's malloc() , merely allocates raw bytes of memory from the free-store, without initializing them. It returns void * rather than Widget* which is why you need to cast the result explicitly.

At this stage, warr is a pointer to raw memory. You can't access its elements because they haven't been initialized yet. To initialize individual elements, call placement new once more, for each element you want initialized:

void assign(Widget arr[], size_t & sz,  const Widget& init)
{
    
new (&arr[sz++]) Widget (init); //invoke copy ctor
}

assign() passes the address of an individual element to placement new which in turn invokes Widget 's copy constructor. The copy-constructor initializes that element with init . Using this technique, you can initialize elements selectively, leaving the rest of the array uninitialized.

To destroy such an array, invoke the destructor of every initialized object. Then call the global operator delete to reclaim the raw storage:

void destroy(Widget arr[], size_t & sz)
{
    
while (sz)
    {
        arr[
--sz].~Widget();//destroy all initialized elements
    }
     ::
operator delete (arr); //reclaim raw storage
}

Summary

The techniques I've presented here are bug prone. Therefore, they should be encapsulated in higher-level classes that hide the implementation details from users. These techniques aren't rarely-used as they might seem. STL allocators use them under the hood to avoid object initialization and minimize reallocations.



posted on 2009-08-13 00:48 Marcky 閱讀(379) 評論(0)  編輯 收藏 引用 所屬分類: C/C++

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲欧美日韩国产中文 | 日韩亚洲欧美一区| 麻豆久久精品| 亚洲欧洲一区二区在线观看| 亚洲电影免费观看高清完整版| 老司机成人网| 亚洲天堂男人| 午夜一区二区三区不卡视频| 国产亚洲福利一区| 欧美成人免费网站| 欧美日韩在线不卡一区| 欧美一级久久久| 久久久在线视频| 中日韩高清电影网| 欧美在线观看www| 日韩一区二区福利| 亚洲欧美文学| 亚洲精品国产精品国自产观看| 最新成人在线| 国产欧美精品va在线观看| 美女日韩在线中文字幕| 欧美日韩国产在线| 久久久亚洲欧洲日产国码αv| 午夜性色一区二区三区免费视频| 亚洲综合精品四区| 亚洲黄色成人久久久| 亚洲一区二区三区免费观看| 在线成人h网| 亚洲一区二区三区免费视频| 亚洲国产成人高清精品| 亚洲一级黄色| a91a精品视频在线观看| 午夜日韩激情| 亚洲午夜高清视频| 欧美1区3d| 久久久精品久久久久| 欧美日韩国产电影| 玖玖视频精品| 国产欧美日韩亚洲一区二区三区| 91久久精品国产91性色tv| 国内一区二区三区在线视频| 一区二区三区回区在观看免费视频| 在线成人h网| 午夜亚洲激情| 午夜欧美理论片| 欧美日韩国产在线看| 欧美激情麻豆| 影音先锋日韩资源| 久久动漫亚洲| 久久精品视频在线观看| 国产精品国产精品国产专区不蜜| 亚洲成人在线视频网站| 国产揄拍国内精品对白| 亚洲欧美日韩精品久久久| 亚洲视频每日更新| 欧美日本高清| 亚洲麻豆av| 一本色道久久88精品综合| 久久久蜜臀国产一区二区| 欧美激情精品久久久久久| 欧美成人午夜激情在线| 亚洲国产mv| 免费在线成人| 亚洲第一黄网| 亚洲精品中文在线| 欧美精品1区2区3区| 亚洲国产网站| 99热在线精品观看| 欧美日韩一区二区免费在线观看| 亚洲人www| 亚洲先锋成人| 国产目拍亚洲精品99久久精品| 亚洲网站视频| 久久精品国产77777蜜臀| 国产精品一区二区久激情瑜伽| 亚洲国产福利在线| 欧美在线91| 91久久精品美女| 欧美成人激情视频免费观看| 亚洲高清一区二区三区| 在线视频亚洲一区| 欧美系列一区| 久久精品一区二区三区不卡| 男人的天堂亚洲在线| 亚洲精品在线看| 国产精品久久久一区二区| 欧美一区二区私人影院日本| 欧美3dxxxxhd| 一区二区三区视频在线播放| 国产精品视频九色porn| 久久久久久久一区二区三区| 亚洲国产精品悠悠久久琪琪 | 欧美与黑人午夜性猛交久久久| 老牛影视一区二区三区| 亚洲精品专区| 国产伦精品一区二区三区在线观看 | 一区二区三区视频观看| 国产日本欧美在线观看| 麻豆精品在线视频| 亚洲专区一区| 亚洲国产精品美女| 久久国产精品高清| 亚洲精品在线观看免费| 国产亚洲精品久久久久动| 欧美成人午夜77777| 午夜精品福利在线| 亚洲激情影院| 久久久久久久性| 亚洲无玛一区| 亚洲国产一二三| 国产亚洲一区精品| 欧美视频成人| 欧美激情一区二区三区成人 | 亚洲二区精品| 久久9热精品视频| 一本色道久久综合| 永久久久久久| 国产婷婷色一区二区三区四区| 欧美久久电影| 免费成年人欧美视频| 欧美一区视频在线| 亚洲一区国产| 国产精品99久久久久久有的能看 | 国产精品理论片在线观看| 另类成人小视频在线| 欧美一区二区三区啪啪| 国产精品99久久久久久www| 亚洲国产一区二区三区在线播 | 亚洲黄色精品| 在线看无码的免费网站| 国产日韩欧美精品综合| 国产精品国产三级国产普通话99 | 久久久av毛片精品| 午夜精品福利视频| 亚洲欧美日韩综合| 亚洲制服丝袜在线| 亚洲影院在线| 亚洲综合精品四区| 亚洲一区在线看| 亚洲午夜精品一区二区三区他趣| 亚洲精品看片| 亚洲美女视频在线观看| 亚洲人成亚洲人成在线观看| 亚洲激情第一区| 亚洲日本中文字幕| 亚洲精品一区二| a91a精品视频在线观看| 亚洲图片在线观看| 午夜精品久久| 久久久久青草大香线综合精品| 久久久无码精品亚洲日韩按摩| 久久久91精品国产| 欧美成人日韩| 欧美三级欧美一级| 国产伦精品一区二区三区| 国产一区二区精品丝袜| 国产一区二区三区免费在线观看 | 欧美日韩999| 国产精品草莓在线免费观看| 国产精品青草久久| 一区二区三区自拍| 日韩小视频在线观看专区| 一道本一区二区| 欧美制服丝袜| 欧美韩国日本一区| 亚洲美女av在线播放| 亚洲中字在线| 久久综合色播五月| 欧美日韩一区二区三区在线观看免| 国产精品v片在线观看不卡| 国产日韩欧美a| 亚洲精品一区二区三区蜜桃久| 一区二区三区偷拍| 久久精品国产综合精品| 欧美激情视频给我| 亚洲一区二区免费在线| 久久综合久久综合久久综合| 欧美日韩中文字幕日韩欧美| 国产真实乱偷精品视频免| av不卡在线| 久久久水蜜桃av免费网站| 亚洲免费精品| 久久手机精品视频| 国产精品美女主播| 亚洲国产精品精华液网站| 亚洲男人的天堂在线| 欧美激情亚洲国产| 午夜精品在线| 欧美日韩国产成人在线| 激情综合色综合久久| 国产精品99久久久久久人| 久久五月婷婷丁香社区| 中文一区二区| 欧美成人一区二区三区片免费| 一本色道久久综合亚洲二区三区| 欧美在线免费观看亚洲| 欧美视频二区36p| 亚洲精品专区| 欧美成人精品福利| 久久精品国产99|