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

鍵盤上的舞者

My Email: marckywu@gmail.com
隨筆 - 19, 文章 - 0, 評(píng)論 - 3, 引用 - 0
數(shù)據(jù)加載中……

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 閱讀(389) 評(píng)論(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>
            久久岛国电影| 亚洲日本一区二区| 亚洲日本在线视频观看| 国产原创一区二区| 亚洲视频第一页| 99视频精品全部免费在线| 久久不射2019中文字幕| 亚洲欧美日韩一区在线| 欧美日韩aaaaa| 亚洲高清免费视频| 亚洲电影成人| 久久精品国产免费观看| 久久精品盗摄| 国产欧美精品一区二区色综合| 亚洲美女免费精品视频在线观看| 亚洲第一精品福利| 久久久久久精| 美女精品在线观看| 一区二区三区在线视频播放| 欧美在线播放视频| 久久av一区二区三区亚洲| 国产精品区一区二区三| 国产精品99久久久久久宅男| 亚洲香蕉网站| 国产精品国产馆在线真实露脸| 亚洲精品国久久99热| 日韩视频免费在线观看| 欧美久久综合| 一本久久综合| 亚洲欧美另类久久久精品2019| 国产精品福利在线观看网址| 一区二区国产精品| 亚洲欧美一区二区激情| 国产精品美腿一区在线看 | 久久精品国产一区二区三| 久久激情综合网| 黄色成人在线网站| 免费人成精品欧美精品| 亚洲精品国产精品国产自| 宅男66日本亚洲欧美视频| 国产精品久久久久9999高清| 亚洲欧美国产毛片在线| 久久九九99| 日韩视频免费在线观看| 国产精品成人观看视频免费| 午夜精品久久久久久久蜜桃app | 欧美日韩国产综合一区二区 | 亚洲国产欧美久久| 一本色道久久88综合亚洲精品ⅰ | 亚洲第一精品福利| 欧美日韩另类国产亚洲欧美一级| 亚洲一区二区久久| 久久久一二三| 亚洲三级免费| 国产精品美女久久久免费| 久久九九久精品国产免费直播| 亚洲国产精品一区二区www| 国产精品99久久久久久久vr | 欧美一级午夜免费电影| 亚洲第一区在线观看| 欧美日本亚洲视频| 欧美一区二区视频在线| 亚洲国产精品传媒在线观看 | 国产欧美日韩另类一区| 美女国内精品自产拍在线播放| 99热免费精品在线观看| 久久只精品国产| 亚洲一二三区在线| 亚洲黄色天堂| 国产日韩欧美综合精品| 欧美精品黄色| 久久久天天操| 香蕉久久夜色精品| 99精品国产99久久久久久福利| 免费毛片一区二区三区久久久| 亚洲欧美久久| 日韩视频在线播放| 亚洲第一精品夜夜躁人人爽| 国产精品一区二区三区四区五区| 欧美成年人视频网站| 欧美一二三视频| av成人福利| 亚洲欧洲另类| 女女同性精品视频| 久久精彩免费视频| 亚洲欧美在线看| 亚洲一区二区三区欧美| 亚洲日本中文字幕| 亚洲高清不卡av| 黄色一区二区三区四区| 国产色综合天天综合网| 国产精品视频导航| 欧美日韩综合| 欧美日韩成人综合在线一区二区| 久久亚洲影院| 久久亚洲精品一区二区| 久久人人97超碰精品888| 久久大香伊蕉在人线观看热2| 亚洲欧美日韩久久精品| 亚洲在线成人精品| 亚洲综合清纯丝袜自拍| 亚洲视频在线二区| 一区二区三区 在线观看视频| 亚洲美女在线一区| 99热在线精品观看| 亚洲视频一区在线观看| 亚洲一区二区三区四区五区午夜 | 亚洲第一福利在线观看| 欧美成人免费在线观看| 欧美高清在线一区| 亚洲激情不卡| 亚洲精品日产精品乱码不卡| 亚洲精品综合久久中文字幕| 亚洲精品偷拍| 中文日韩电影网站| 亚洲欧美日韩在线不卡| 欧美一级播放| 久久亚洲欧洲| 欧美日韩国产一区二区三区地区| 欧美日韩中文精品| 国产精品视频区| 国产亚洲成人一区| 伊人色综合久久天天| 亚洲精品小视频在线观看| 亚洲精选大片| 午夜精品福利一区二区蜜股av| 久久精品官网| 欧美成人激情在线| 一本色道综合亚洲| 欧美一区网站| 免费成人在线观看视频| 欧美日韩在线播放三区| 国产欧美一区二区三区另类精品| 狠狠色香婷婷久久亚洲精品| 亚洲欧洲精品天堂一级| 亚洲综合视频一区| 老色鬼久久亚洲一区二区| 亚洲国产色一区| 亚洲欧美变态国产另类| 久久综合久久久| 国产精品国产三级国产专播精品人 | 开心色5月久久精品| 欧美日韩一区二区在线播放| 国产三级欧美三级| 亚洲毛片在线| 欧美在线一区二区| 亚洲人成人99网站| 欧美在线1区| 欧美日韩精品综合| 在线观看一区视频| 亚洲影院在线| 亚洲国产精品福利| 午夜精品久久久久久久久久久久久 | 欧美极品在线播放| 国产一区二区三区免费在线观看| 亚洲人成欧美中文字幕| 久久精品国产99精品国产亚洲性色| 欧美电影在线免费观看网站| 亚洲一区欧美一区| 欧美精品日韩www.p站| 伊人婷婷欧美激情| 欧美一区二区三区久久精品| 亚洲国产日韩欧美在线99| 欧美亚洲一区二区三区| 欧美日韩国产专区| 亚洲国产欧美不卡在线观看| 久久九九国产精品怡红院| 亚洲午夜免费视频| 欧美精品激情| 亚洲人屁股眼子交8| 久久久蜜桃一区二区人| 亚洲午夜国产成人av电影男同| 免费看亚洲片| 亚洲高清免费| 久久亚洲欧洲| 欧美一区二区三区四区夜夜大片 | 99精品欧美一区二区三区| 久久综合九色综合久99| 国产亚洲精品久久久久婷婷瑜伽| 亚洲深夜福利在线| 亚洲日本在线视频观看| 欧美激情2020午夜免费观看| 在线观看日韩欧美| 嫩草成人www欧美| 久久久久久成人| 精品不卡一区二区三区| 久久久免费精品| 欧美一区二区日韩| 国产日韩欧美在线视频观看| 欧美一区二区三区视频在线观看 | 午夜影视日本亚洲欧洲精品| 国产精品久久久久影院亚瑟| 亚洲欧美亚洲| 亚洲永久免费| 国产亚洲一区二区三区在线观看| 欧美一区二区三区在线| 欧美一区二区三区免费观看| 国产在线日韩| 免费在线欧美黄色| 欧美大胆成人|