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

鍵盤上的舞者

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>
            影音先锋欧美精品| 亚洲欧美国产毛片在线| 欧美成人精品h版在线观看| 亚洲国产日韩美| 亚洲一二三四久久| 伊人久久综合| 在线亚洲欧美专区二区| 激情五月综合色婷婷一区二区| 亚洲国产精品久久久久秋霞影院 | 亚洲欧美在线x视频| 久久精品久久综合| 一区二区三区视频观看| 久久久久99| 欧美亚洲视频在线观看| 欧美精品在线播放| 亚洲丰满少妇videoshd| 国产视频久久久久久久| 夜夜夜精品看看| 亚洲欧洲美洲综合色网| 亚洲综合二区| 亚洲激情成人网| 久久久无码精品亚洲日韩按摩| 午夜精品久久久久99热蜜桃导演| 欧美成人国产一区二区| 狂野欧美激情性xxxx| 狠狠久久五月精品中文字幕| 亚洲摸下面视频| 久久精品国产成人| 国内精品久久久久影院优| 欧美一区二区日韩| 欧美1区视频| 亚洲精品影视| 国产精品久久久久久久久免费樱桃| 久久不射网站| 日韩亚洲国产精品| 久久综合久久久久88| 国内揄拍国内精品少妇国语| 欧美在线电影| 亚洲激情在线播放| 亚洲一区二区四区| 国产在线乱码一区二区三区| 久久国产精品99精品国产| 久久亚洲私人国产精品va| 日韩视频二区| 国产美女精品在线| 欧美3dxxxxhd| 欧美一区二区视频观看视频| 亚洲大胆美女视频| 午夜精品福利一区二区蜜股av| 猛干欧美女孩| 午夜精品福利在线观看| 亚洲精品久久久久久久久| 国产日韩精品一区| 欧美婷婷六月丁香综合色| 久久在线免费| 亚洲一区二区伦理| 亚洲国产一二三| 樱花yy私人影院亚洲| 国产精品久久久| 欧美精品亚洲| 欧美日韩另类一区| 欧美丝袜一区二区| 欧美国产一区二区| 欧美福利视频网站| 欧美高清自拍一区| 欧美成人精品一区二区三区| 久久色在线观看| 六月婷婷一区| 欧美精品一区二区视频| 欧美激情视频一区二区三区免费 | 精品69视频一区二区三区| 精品福利电影| 亚洲毛片av在线| 亚洲一区二区精品视频| 久久久99国产精品免费| 久久精品国亚洲| 欧美二区不卡| 国产精品99久久不卡二区| 午夜精品视频在线观看| 欧美高清视频一区二区三区在线观看| 老色鬼精品视频在线观看播放| 欧美日韩高清在线观看| 狠狠88综合久久久久综合网| 一本一道久久综合狠狠老精东影业 | 国产亚洲一二三区| 亚洲人成网站在线播| 亚洲私拍自拍| 欧美激情亚洲精品| 国产色综合网| 亚洲精品乱码久久久久久蜜桃麻豆| 亚洲在线视频一区| 一本大道久久a久久精二百| 国产欧美一区二区白浆黑人| 亚洲精品久久久久久久久久久| 久久国产精品99国产| 日韩午夜激情| 欧美日韩亚洲另类| 亚洲精品在线视频观看| 久久综合色婷婷| 欧美亚洲尤物久久| 国产欧美精品一区aⅴ影院| 9色porny自拍视频一区二区| 欧美国产视频日韩| 久久久免费精品视频| 国外成人在线| 久久综合给合久久狠狠狠97色69| 欧美黄色精品| 在线观看视频一区二区欧美日韩 | 欧美高潮视频| 99成人在线| 午夜精品久久99蜜桃的功能介绍| 国产精品劲爆视频| 亚洲欧美电影院| 欧美日韩国产bt| 亚洲一区二区三区四区中文| 99re热精品| 国产一区二区成人久久免费影院| 欧美高清视频www夜色资源网| 亚洲精品社区| 亚洲香蕉视频| 亚洲国产精品成人| 亚洲一区在线播放| 亚洲乱亚洲高清| 亚洲欧美区自拍先锋| 亚洲高清视频在线| 亚洲专区一二三| 日韩一区二区高清| 久久九九国产精品怡红院| 一区二区三区免费看| 久久精品欧洲| 午夜精彩国产免费不卡不顿大片| 麻豆国产va免费精品高清在线| 亚洲一区亚洲二区| 欧美成人精品影院| 蜜臀久久99精品久久久久久9 | 亚洲精品久久久蜜桃| 国内不卡一区二区三区| 亚洲一区在线免费| 亚洲一区欧美一区| 欧美私人网站| 一区二区三区国产精华| 日韩亚洲欧美一区| 欧美激情偷拍| a91a精品视频在线观看| 亚洲午夜精品视频| 国产精品久久久久久久久久免费| 亚洲免费观看高清完整版在线观看熊 | 亚洲午夜视频在线观看| 一区二区三区视频在线| 欧美日韩在线播放一区| 在线亚洲自拍| 久久综合伊人77777蜜臀| 亚洲国产一区二区精品专区| 亚洲欧洲另类| 国产精品久久999| 久久精品99国产精品酒店日本| 欧美成人一区二区三区在线观看| 99热在线精品观看| 国产一区二区在线观看免费| 欧美国内亚洲| 欧美激情亚洲国产| 国产精品视频观看| 国产精品99久久久久久久久久久久 | 欧美精品国产精品日韩精品| 亚洲精品美女在线观看| 亚洲手机在线| 在线观看av一区| 国产精品国产三级国产aⅴ入口| 久久久久久免费| 亚洲一区二区三区四区中文| 亚洲高清在线观看| 蜜桃av一区二区三区| 欧美淫片网站| 亚洲尤物在线视频观看| 国产精品99久久不卡二区| 亚洲人成人一区二区在线观看| 国产欧美综合一区二区三区| 国产精品二区在线| 日韩一区二区电影网| 最近看过的日韩成人| 亚洲日本黄色| 亚洲一区二区黄| 亚洲欧美日韩天堂| 久久福利资源站| 久久中文字幕一区| 免费成人av在线| 亚洲高清不卡在线| 亚洲精品五月天| 亚洲午夜激情免费视频| 亚洲欧美久久久| 老牛国产精品一区的观看方式| 欧美xart系列在线观看| 欧美另类在线观看| 国产欧美精品一区aⅴ影院| 国产一区二区成人| 亚洲精品一区二区三区不| 一级成人国产| 欧美一级欧美一级在线播放| 欧美激情成人在线| 亚洲视频一区在线|