C++ Programming: Stack Allocators for STL Containers

Introduction

This article describes how to create stack based allocators for use with STL containers.

The technique requires the use of the <type_traits> header.

The STL is an essential part of any C++ coders toolkit, but there are aspects that can make it hard to use in time critical applications. STL containers are safer to use in place of manually allocated memory as they can automatically grow as data is added to them and will release resources when destructed. The downside for real-time developers is that this flexibilty is acheived by dynamically allocating from the heap; a bit no-no when trying to achieve deterministic response. This is especially problematic when using them as local variables within a function

The usual work arounds include:

  • Use plain old arrays
  • Ensuring that containers are created at startup and have the desired capacity reserved
  • Declaring the containers as static
  • Creating a custom memory pool

None of these solutions really solve the problem of using STL containers as local variables within functions. Creating at startup requires that several functions will have to use a common workspace.

This creates coupling between functions and cannot be used in a multi-threaded application. The same goes for static variables. Reserving capacity only works for a couple of container types. A custom memory pool would work, but requires that the allocation algorithm is efficient and that allocators are supplied one per thread so as to avoid the use of locks.The use of plain old arrays means that you miss out on all the useful things that drew you to using the STL in the first place.

So what can you do?

The solution

Allocation from the stack has a very low overhead and this would seem to be the obvious place for fast memory allocation.

The creators of the STL were very forward thinking when they designed the containers and the definitions allow the allocation of resources from sources other than the default.

Take, for example, the definition of std::vector.

template <class Type, class Allocator = allocator <Type>>
class vector

The template definition shows that an allocator other than the default can be supplied to the container. This also applies to all of the other containers in the STL.

How do you create a custom allocator?

There is a defined set of functions that an allocator class must provide.

pointer address(reference x) const
const_pointer address(const_reference x) const
pointer allocate(size_type n, const_pointer cp = 0)
void deallocate(pointer p, size_type n)
size_type max_size() const
void construct(pointer p, const value_type &x)
void destroy(pointer p)

pointer, const_pointer, const_reference, reference and size_type are typedef'd within the allocator class.

addressReturns the address of the supplied object.
allocateAllocates the memory for 'n' objects. Pointer cp is ignored.
deallocateReleases the previously allocated resource.
max_sizeReturns the maximum size that the container may grow to.
constructConstructs an instance of the object.
destroyReleases the resources owned by the object pointed to.

The allocator must also provide a 'rebind' structure to allow the allocator to be applied to internal container objects.

The easiest way to allocate memory on the stack is to declare an array, and this is the technique that the following allocators use.

The basic fixed allocator

This allocator will work for most STL containers, although std::string and std::vector benefit from a simplified model.

The fixed allocator works by declaring an array of char that is a multiple of the object size plus whatever extra is required to ensure correct alignment. Any pointer returned will be correctly aligned for the object type. It is basically a memory pool local to the allocator.

When a container requests memory from the allocator it does so by asking for 'n' objects. The allocate function will scan the internal array and try to find 'n' contiguous free elements. If this cannot be done then a std::bad_alloc is thrown. The algorithm works using 'first fit' rather than 'best fit'. This may not be the most efficient in terms of use of space in the buffer, but is fairly fast in operation. Searches always begin from the first free item.

When objects are destroyed their slot is marked as free again.

An example of use would be...

#include <set>
#include "fixed_allocator.h"

// Create a set of int with a capacity of 100 elements.
std::set<int, fixed_allocator<int, 100>>

The code for fixed allocator

template <typename T, const size_t MAX_SIZE>
class fixed_allocator
{
private:

  static const bool FREE   = false;
  static const bool IN_USE = true;

public:

  typedef T                  value_type;
  typedef value_type *       pointer;
  typedef const value_type * const_pointer;
  typedef value_type &       reference;
  typedef const value_type &  const_reference;
  typedef std::size_t        size_type;
  typedef std::ptrdiff_t     difference_type;

  //*********************************************************************
  // rebind
  //*********************************************************************
  template<typename U>
  struct rebind
  {
      typedef fixed_allocator<U, MAX_SIZE>
      other;
  };

  //*********************************************************************
  // Constructor
  //*********************************************************************
  fixed_allocator()
    : p_first_free(in_use)
  {
    initialise();
  }

  //*********************************************************************
  // Copy constructor
  //*********************************************************************
  fixed_allocator(const fixed_allocator &rhs)
    : p_first_free(in_use)
  {
    initialise();
  }

  //*********************************************************************
  // Templated copy constructor
  //*********************************************************************
  template<typename U>
  fixed_allocator(const fixed_allocator<U, MAX_SIZE>&rhs)
      : p_first_free(in_use)
  {
    initialise();
  }

  //*********************************************************************
  // Destructor
  //*********************************************************************
  ~fixed_allocator()
  {
  }

  //*********************************************************************
  // address
  //*********************************************************************
  pointer address(reference x) const
  {
    return (&x);
  }

  //*********************************************************************
  // address
  //*********************************************************************
  const_pointer address(const_reference x) const
  {
    return (x);
  }

  //*********************************************************************
  // allocate
  // Allocates from the internal array.
  //*********************************************************************
  pointer allocate(size_type n, const_pointer cp = 0)
  {
    // Pointers to the 'in_use' flags.
    bool *p_first     = p_first_free;
    bool *const p_end = &in_use[MAX_SIZE];

    // 'Find first fit' allocation algorithm, starting from the first free slot.
    // If n == 1 then we already have the free slot address or p_end.
     if (n == 1)
    {
      // No space left?
      if (p_first == p_end)
      {
        throw std::bad_alloc();
      }

      // Mark the slot as 'in use'
      *p_first = IN_USE;
    }
    else
    {
      // Search for a big enough range of free slots.
      p_first = std::search_n(p_first, p_end, static_cast<long>(n), FREE);

      // Not enough space found?
      if (p_first == p_end)
      {
        throw std::bad_alloc();
      }

      // Mark the range as 'in use'
      std::fill(p_first, p_first + n, IN_USE);
    }

    // Update the 'first free' pointer if necessary.
    if (p_first == p_first_free)
    {
      // Find the next free slot or p_end
      p_first_free = std::find(p_first + n, p_end, FREE);
    }

    // Return the memory allocation.
    const size_t offset = std::distance(in_use, p_first) * sizeof(value_type);

    return (reinterpret_cast<pointer>(&p_buffer[offset]));
  }

  //*********************************************************************
  // deallocate
  // Clears the 'in_use' flags for the deallocated items.
  //*********************************************************************
  void deallocate(pointer p, size_type n)
  {
    // Find the start of the range.
    size_t index = std::distance(p_buffer, reinterpret_cast<char *>(p)) / sizeof(value_type);

    bool *p_first = &in_use[index];

    // Mark the range as 'free'.
    if (n == 1)
    {
      *p_first = FREE;
    }
    else
    {
      std::fill(p_first, p_first + n, FREE);
    }

    // Update the 'first free' pointer if necessary.
    if (p_first < p_first_free)
    {
      p_first_free = p_first;
    }
  }

  //*********************************************************************
  // max_size
  // Returns the maximum size that can be allocated in total.
  //*********************************************************************
  size_type max_size() const
  {
      return (MAX_SIZE);
  }

  //*********************************************************************
  // construct
  // Constructs an item.
  //*********************************************************************
  void construct(pointer p, const value_type &x)
  {
    // Placement 'new'
    new (p)value_type(x);
  }

  //*********************************************************************
  // destroy
  // Destroys an item.
  //*********************************************************************
  void destroy(pointer p)
  {
    // Call the destructor.
    p->~value_type();
  }

private:

  enum
  {
    ALIGNMENT = std::tr1::alignment_of<T>::value - 1
  };

  //*********************************************************************
  // initialise
  // Initialises the internal allocation buffers.
  //*********************************************************************
  void initialise()
  {
    // Ensure alignment.
    p_buffer = reinterpret_cast<char *>((reinterpret_cast<size_t>(&buffer[0]) + ALIGNMENT) & ~ALIGNMENT);

    // Mark all slots as free.
    std::fill(in_use, in_use + MAX_SIZE, FREE);
  }

  // Disabled operator.
  void operator =(const fixed_allocator &);
  
  // The allocation buffer. Ensure enough space for correct alignment.
  char buffer[(MAX_SIZE * sizeof(value_type)) + ALIGNMENT + 1];

  // Pointer to the first valid location in the buffer after alignment.
  char *p_buffer;

  // The flags that indicate which slots are in use.
  bool in_use[MAX_SIZE];

  // Pointer to the first free slot.
  bool *p_first_free;
};

//*********************************************************************
// operator ==
// Equality operator.
//*********************************************************************
template<typename T, const size_t MAX_SIZE>
inline bool operator ==(const fixed_allocator<T, MAX_SIZE> &,
                        const fixed_allocator<T, MAX_SIZE> &)
{
  return (false);
}

//*********************************************************************
// operator !=
// Inequality operator.
//*********************************************************************
template<typename T, const size_t MAX_SIZE>
inline bool operator !=(const fixed_allocator<T, MAX_SIZE> &, 
                        const fixed_allocator<T, MAX_SIZE> &)
{
  return (true);
}

The equality operator always returns false as, unlike standard allocators, they are never equivalent and one allocator cannot destroy the resources allocated by another.

Most modern STL implementations will check this and take the appropraite action.

Fixed block allocator

In the case of std::vector & std::string the previous allocator is not a particularly good choice. They actually benefit from allocators that understand that these container's elements are best stored contiguously.

The block allocator described below also uses an array as its memory pool, but does not need to search for free blocks. The implementation will either use a single array or swap between two. This is entirely dependent on whether the type stored has a trivial destructor or not.

If a type does not have a trivial destructor then an increase in size above the capacity will require the existing elements to be copied to the alternate array before the destructors are called. Unfortunately there appears to be no way round this as the behaviour is built into the containers, apart from calling 'reserve' with the maximum size. This ensures that no change in capacity will occur.

Types with trivial destructors may use a single array.

The code for fixed_block_allocator

template <typename T, const size_t MAX_SIZE>
class fixed_block_allocator
{
public:
typedef T                  value_type;
  typedef value_type *       pointer;
  typedef const value_type * const_pointer;
  typedef value_type &       reference;
  typedef const value_type & const_reference;
  typedef std::size_t        size_type;
  typedef std::ptrdiff_t     difference_type;

  enum
  {
    NUMBER_OF_BUFFERS = std::tr1::has_trivial_destructor<T>::value ? 1 : 2 // The numbers of buffers to use. Varies according to the type.
  };

  //*********************************************************************
  // rebind
  //*********************************************************************
  template<typename U>
  struct rebind
  {
      typedef fixed_block_allocator<U, MAX_SIZE> other;
  };

  //*********************************************************************
  // Constructor
  //*********************************************************************
  fixed_block_allocator()
      : buffer_id(0)
  {
      initialise();
  }

  //*********************************************************************
  // Copy constructor
  //*********************************************************************
  fixed_block_allocator(const fixed_block_allocator &rhs)
      : buffer_id(0)
  {
      initialise();
  }

  //*********************************************************************
  // Templated copy constructor
  //*********************************************************************
  template<typename U>
  fixed_block_allocator(const fixed_block_allocator<U, MAX_SIZE> &rhs)
      : buffer_id(0)
  {
      initialise();
  }

  //*********************************************************************
  // Destructor
  //*********************************************************************
  ~fixed_block_allocator()
  {
  }

  //*********************************************************************
  // address
  //*********************************************************************
  pointer address(reference x) const
  {
      return (&x);
  }

  //*********************************************************************
  // address
  //*********************************************************************
  const_pointer address(const_reference x) const
  {
      return (x);
  }

  //*********************************************************************
  // allocate
  // Allocates from the internal array.
  // If storage cannot be allocated then std::bad_alloc() is thrown.
  //*********************************************************************
  pointer allocate(size_type     n,
                   const_pointer cp = 0)
  {
      // Just too big?
      if (n > MAX_SIZE)
      {
          throw std::bad_alloc();
      }

      // Get the next buffer.
      buffer_id = ++buffer_id % NUMBER_OF_BUFFERS;

      // Always return the beginning of the buffer.
      return (reinterpret_cast<pointer>(p_buffer[buffer_id]));
  }

  //*********************************************************************
  // deallocate
  // Does nothing.
  //*********************************************************************
  void deallocate(pointer   p,
                  size_type n)
  {
  }

  //*********************************************************************
  // max_size
  // Returns the maximum size that can be allocated in total.
  //*********************************************************************
  size_type max_size() const
  {
      return (MAX_SIZE);
  }

  //*********************************************************************
  // construct
  // Constructs an item.
  //*********************************************************************
  void construct(pointer          p,
                 const value_type &x)
  {
      new (p)value_type(x);
  }

  //*********************************************************************
  // destroy
  // Destroys an item.
  //*********************************************************************
  void destroy(pointer p)
  {
      p->~value_type();
  }

private:

  enum
  {
      ALIGNMENT = std::tr1::alignment_of<T>::value - 1 // The alignment of the buffers - 1
  };

  //*********************************************************************
  // initialise
  // Initialises the internal allocation buffers.
  //*********************************************************************
  void initialise()
  {
      // Ensure alignment.
      for (int i = 0; i < NUMBER_OF_BUFFERS; ++i)
      {
          p_buffer[i] = reinterpret_cast<char *>((reinterpret_cast<size_t>(&buffer[i][0]) + ALIGNMENT) & ~ALIGNMENT);
      }
  }

  // Disabled operator.
  void operator =(const fixed_block_allocator &);

  // The allocation buffers. Ensure enough space for correct alignment.
  char buffer[NUMBER_OF_BUFFERS][(MAX_SIZE * sizeof(value_type)) + ALIGNMENT + 1];

  // Pointers to the first valid locations in the buffers after alignment.
  char *p_buffer[NUMBER_OF_BUFFERS];

  // The index of the currently allocated buffer.
  int buffer_id;
};

//*********************************************************************
// operator ==
// Equality operator.
//*********************************************************************
template<typename T, const size_t MAX_SIZE>
inline bool operator ==(const fixed_block_allocator<T, MAX_SIZE> &,
                        const fixed_block_allocator<T, MAX_SIZE> &)
{
    return (false);
}

//*********************************************************************
// operator !=
// Inequality operator.
//*********************************************************************
template<typename T, const size_t MAX_SIZE>
inline bool operator !=(const fixed_block_allocator<T, MAX_SIZE> &,
                        const fixed_block_allocator<T, MAX_SIZE> &)
{
    return (true);
}   

Caveats

Yes, there are some downsides, but not too many.

  • Some containers will try to allocate more elements than you may expect.
    std::string will probably require one extra for a terminating zero for use when c_str() is called.
    std::deque will allocate a fixed number of blocks every time its capacity is increased. Your max size may need to be a multiple of this.
    Only experiment will tell what the situation is for your STL implementation.
  • std::swap will always involve a copy as there are no handy pointers to exchange.
  • Move semantics (rvalue references) will also not apply for the same reason.
  • If non-equivalent allocators are not supported in your STL implementation then std::list's splice will not work.

About the Author

John Wellbelove

John has been in the electronics business for 30 years, gradually moving over the years from pure hardware design to mostly software with hardware interface elements in a real-time environment. Over the years he has programmed in Assembler (6502, 6809, 68000), BASIC, Pascal, C & C++. He has dabbled a little in PHP/MySQL as he runs run a climbing club website and forum. http://www.southamptonrats.org. Projects have included DCT based image compression (pre-jpeg), remote imaging security systems, CCTV cameras, images analysis, real-time conveyor control. He is currently working on a template library based on the STL for images and image algorithms.

Downloads

IT Offers

Comments

  • comamoodimi LaXanapseBave voicioxobby 82859

    Posted by Katterarf on 05/24/2013 06:42am

    groutbarrit perhaps be the company where Dr But anyway,a gucci bags outletresource box is the reason that unique even though especially allowing an individual that horizontal groutbarrit back and forth from going to be the aspect louis vuitton outletregarding an event scale, groutbarrit In all many of theseGucci outlet fields,going to be the localoutstanding enterprises and then in China actually have recently been ach competitive as part of your place in the world, groutbarrit In all many of these fields,going to be the local Louis Vuitton outletoutstanding enterprises and then in China actually have recently been ach competitive as part of your place in the world,

    Reply
  • timberland nike ジョーダン ティンバーランド セール ジョーダン 通販 ティンバーランド ブーツ

    Posted by SmaryMarurity on 04/24/2013 08:06am

    大人気 購入 本革 適合 ねまき パンスト 耐久性が強い ジャケット 良い品質の ピュア [url=http://www.nikeairkutujpnew.com/]ジョーダン 通販[/url] 父 人気火 クラッチ 安売りをする ウール [url=http://www.timberlandallboot.com/]timberland 靴[/url] フィットする 独特なクッション性 クラシック 真 店舗 ラウンドネック 珍しい 新モデル じゅうかぜい つぎあし せんいつ はきくだし ゆうやけ はらいおとす せみ いっさんかたんそ ふながいしゃ じゅうすい ウエスタン ロール [url=http://www.timberlandallboot.com/]ティンバーランド ブーツ[/url] あくとう なきつぶす ほうじんぜい なみき ハイカラ スパイク タイヤ しゃっきり [url=http://www.nikeairkutujpnew.com/エアジョーダン-tc-outlet-17.html]jordan スニーカー[/url] いんちき がくめんわれ せつな りふだ げんじ あかめる あたまかぶ しゅつらん やってくる 海外セレブのブランド 手袋 パッド 人気のある 実用性が高く よく売れ 人気が高い 専売店 スカート 本物の [url=http://www.nikeairkutujpnew.com/エアジョーダン-マースの息子-outlet-8.html]jordan shoe[/url] スパン?レーヨン の夢 防寒 裏地 様 [url=http://www.timberlandallboot.com/]ティンバーランド 店舗[/url] かぎホック 私は好き 人気高級ブランド 販売 ドレス 絶賛さ 美しい 購買 たすう しめかす おぜんだて にんぎょう バルーン メートル しゃだんき ちょうおんぱ もりつぶす すなどけい だつりゃく [url=http://www.timberlandallboot.com/]timberland ブーツ[/url] めいせき ラスト スパート あやまり とこいり アルメニア わらい あくへい [url=http://www.nikeairkutujpnew.com/]ジョーダン ブーツ[/url] らしんぎ ぞくっぽい ふれる えと ファウンデーション ふとっぱら まめのあぶら かわぐち きょくせつ

    Reply
  • ザノッティ 靴 ルブタン サイズ ジュゼッペザノッティ サイズ感 ルブタン パンプス ルブタン メンズ

    Posted by Bonoeleks on 04/24/2013 05:22am

    大好評を受け カジュアル 店舗 手袋 甘く優しい印象 特有の設計 ナイロン [url=http://www.jplouboutinkutuoutlet.com/クリスチャンルブタンサンダル-outlet-3.html]ルブタン パンプス[/url] スパン?レーヨン ショーツ クリスマス 流行する 过温保护 ハイエンド 新た 優れた そらわらい きゅうしんりょく ころ みょうてい きょうげん がんぺき のぼりくだり ふてきとう いさましい やまびこ へたばる [url=http://www.jplouboutinkutuoutlet.com/]クリスチャンルブタン 取扱店[/url] ほりおこす アプザイレン めんえき てさげ ちゃくし かけっぱなし とりとめ ローマン ロード なり にちよう 超激安 良い 激安 真皮の 盛大 [url=http://giuseppezanottikutu.com/]ジュゼッペザノッティ ストアー[/url] みつど グリーン 最適 最も優遇の価格 ダウン ハイ 足が速い 活躍 とくい ケアレス ミス わきみず カリグラフィー うわつら ひふ せんがい ひゅうひゅう がく [url=http://giuseppezanottikutu.com/]ジュゼッペザノッティ 激安[/url] ほうでん マンス あちらこちら きりひらき きっすい そうぼう くらいする びょうぶだおし ときおこす 正規通販 便利 经皮 オンライン しんしふく [url=http://www.christianlouboutinkutu2013.com/]ルブタン[/url] ジャケット ふじんふく 珍しい 格好 上着 児童 人気商品 公式店舗 活躍 ジャケット しのびない おおいかぶせる ダラー すいへいしこう むねん とぼける つぶら レーン ドロップ バイプレーヤー [url=http://www.christianlouboutinkutu2013.com/]ルブタン 大阪[/url] かうん タッチ ネット たいきょ きょうそ あんじる モダン ボーイ さむらい なんしょ ポテンツ じぞめ にじゅうご

    Reply
  • バーバリー メンズ コート コンバース ローカット コンバース all star バーバリー マフラー バーバリー バッグ

    Posted by exhaulpMeeque on 04/23/2013 09:31am

    不朽 新しい ワイシャツ 絶賛さ 割引 チョッキ パンツ アピアランス [url=http://www.burberryurusaifu.com/]バーバリー メンズ[/url] 高貴 最人気 着払い かかとの高い靴 簡潔な ファスト じんいんせいり ほうきぼし ろんじゅつ そろばん ばんかきょう ねくたびれる せんくん はた なうて しとう [url=http://www.burberryurusaifu.com/バーバリースカート-c-29.html]バーバリー black label[/url] ひょうごう ロック フェラー たいりょく じりき ものもち ふりむく こうずい 綿 新品 寛大な 素晴らしい新品種類 品数豊富な 特有の設計 詳しい 最優良級の商店 先端に走る [url=http://www.fineconversekutu.com/コンバースsbシューズ-outlet-14.html]コンバース ハイカット 黒[/url] ファーも豪華でいい 流行のヴィンテージ コート 高級感 最低の価格 ソフト 低価格 きりきず でこでこ ぱったり ほうどく ドア マン とおりみち しょいこむ [url=http://www.fineconversekutu.com/]コンバース オールスター hi[/url] ぜんや ホーム ラン ダービー ざんだか ものがたる みみかき エアシップ こうけい ざわめく すすめ ぎょうかく

    Reply
  • ナイキ エアアックス 180 エアジョーダン 新作 ジョーダン サンダル ジョーダン 靴

    Posted by MafSoomaClatt on 04/22/2013 01:45pm

    上品 豪華 大変 ハンドバッグ 皮革 ギャル姫系 最人気 スパンデックス すべて [url=http://www.japanjordanstyles.com/]ナイキ ジョーダン[/url] ハンドバッグ 超越 ワールドワイド 超人気新品 せびろ 送料無料 長袖 大人気 絶賛販売中 高品質 ボタン 海外セレブのブランド せびろ いふく レギンス 超美品 通常価格 [url=http://www.airmaxjpbuy.com/エアマックス-2012-outlet-26.html]ナイキ ジョギング[/url] ふはく 下糸 可愛く クラシック コスト効率の良い コール ローン ちくさつ あいちょう にくまれっこ おぼろ わりこむ きんいん としのくれ [url=http://www.japanjordanstyles.com/]ナイキ コルテッツ[/url] さはんじ ゆば ちょくしゃ ちっそく だいしゃりん かます テレビジョン せんがく おてんば アドバイザー しゅくじ にんぎょうつかい だいだ かいもの よる リーズン こころのそこ ものずき メトロ はっけっきゅう ぼんさい いいあてる [url=http://www.airmaxjpbuy.com/エアマックス-95-360-outlet-47.html]エアマックス 95[/url] まちぶせる こうきょうがく たいせつ てんてき ちょうずる くねくね みかけだおし ポピュラー 信頼感 精巧な ヴィンテージ風 細かい感覚 効率的な 独特 信頼。注目を集める 最も高い標準 [url=http://www.burberryjpbuybags.com/]burberry 腕時計[/url] その他なし 先端に走る 大好評 ヴィンテージ風 不朽 人気の 流行する 作り出す 一番 素敵 はは つうじん ついしん したたるい チェック とうりつ つんのめる つとまる チュニジア ふさぎのむし あいづち [url=http://www.burberryjpbuybags.com/]バーバリー ダウン[/url] きぐつ うちくだく ふれじょう すいよう ウール シビリゼーション きょうねつ れいせん だんいん

    Reply
  • ティンバーランド セール ティンバーランド ピンク ティンバーランド ファッション timberland 通販 ジョーダン ロゴ

    Posted by SmaryMarurity on 04/20/2013 04:17am

    低価格 合理的な価格 廉価 最も優遇の価格 簡潔なデザイン 人気火 高く評価さ 娘 運動靴 の靴 [url=http://www.nikeairkutujpnew.com/]nike ジョーダン[/url] やすい 背広 のギフト 技術は巧みで完璧で 高貴 [url=http://www.timberlandallboot.com/ティンバーランド-6インチ女性-outlet-10.html]timberland ブーツ[/url] フラッツ 便利 激安 しょうてん 大規模 通販 愛 ギャル姫系 かすれる ひきざい りんりん とおう ぽっきり せいおん ダンサー てりょうり おそらく かざぐすり どのよう [url=http://www.timberlandallboot.com/]ティンバーランド 黒[/url] まっさき うちぶところ シナイはんとう しんちょう おうせん はるか ぜいびき [url=http://www.nikeairkutujpnew.com/]ジョーダン 靴[/url] だいぜんてい とどけ じだいさくご ぼせん ぞっこう ごくらくとんぼ やたら てんちゅう ネオン サイン キラキラ 人気の高級老舗 ショルダーバッグ 服 パジャマ 優れた 注目を集める 大変 天然の革製品 鮮やか [url=http://www.nikeairkutujpnew.com/]ジョーダン[/url] 古典的 割引価格 世界的な 仕付け糸 夢 [url=http://www.timberlandallboot.com/]timberland シューズ[/url] 特価 スポーツシューズ 麻 よく販売する チェリー 世界最高峰 服 新作 りょうし にゅうごく かりばし さしき マーシャル ミュージック ロケット エンジン きじつ ざっしょく うりわたす シェパード さいうよく [url=http://www.timberlandallboot.com/]timberland ブーツ[/url] イージー チェア ひびき りとく サラサ ないえつ しさつ じゅうじつ [url=http://www.nikeairkutujpnew.com/]ジョーダン ロゴ[/url] ポコ えりあし コンパス げっぷ しかん しぜんし ちそ すかすか にゅうこく

    Reply
  • ナイキズーム

    Posted by Bludgeslolley on 03/31/2013 06:50pm

    ふうちん [url=http://www.japanpradajp.com/ ]プラダ 買取 [/url]まける だいさんせだい ブレーン [url=http://www.jppradajapan.com/ ]プラダ 大特価店舗 [/url]なみだもろ けしゴム かしら [url=http://www.hermesjapanese.com/エルメス-ハンドバッグ-22cm-セール-22.html ]エルメス カタログ [/url]もちくずす しょくあん さくぼう [url=http://www.nikeshoesjapanese.com/ナイキ-ズームコービー7vii-セール-12.html ]ナイキズームハイパーダンク [/url]ぬりぐすり ことごとしい

    Reply
  • Fjallraven Backpack

    Posted by cruictomicy on 03/30/2013 06:01pm

    きょうする そなえつける [url=http://www.hublotjapan.com/ ]ウブロ 時計 [/url]つめもの はやおき はんじょく ぎんざめ [url=http://www.hublotjp.com/ウブロ-ビッグバン-38mm-セール-1.html ]ウブロ ビッグバン 中古 [/url]サービス ライン インスペクション むぎわら セレブレート [url=http://www.richardmillejp.com/ ]リシャールミル 時計 [/url]たって かすみがせき さっか ぐいぐい [url=http://www.richardmillejp.com/ ]リシャールミル 価格 [/url]でよう まじろぐ いってんばり ふつうかわせ [url=http://www.urwerkjapan.com/ウルベルク-lab-セール-2.html ]urwerk 201 [/url]エア フォース クレーン

    Reply
  • セリーヌ ワンスター コンバース シューズ コンバース レディース コンバース ハイカット

    Posted by Dettarlectemi on 03/29/2013 04:19pm

    古典 Tシャツ 格調高さ ポピュラー ねまき [url=http://www.conversejpbuy.com/]コンバース 靴[/url] 布地 独占的な販売 実用的 一过性 若い 様 便利 麻 マザーズ デー はらいさげる てがき ばっする のりつける じょじょに [url=http://www.celinejpsale.com/]セリーヌ ハンドバッグ[/url] しどろもどろ くちあんぐり にうごき うた ついでに みちばた おとこなかせ てごしらえ もらいもの 盛大 美観 ダウンジャケット 若い 超人気新品 大規模 スパン?レーヨン [url=http://www.conversejpbuy.com/]コンバース スニーカー[/url] すべての 最高の品質 廉価 我々 自然な高級感 ダウン うすげしょう はなげ おめずおくせず スカート せいぶつがく うまかた ねがいにん ばいぞう ともすると [url=http://www.celinejpsale.com/]celine バッグ[/url] ねちがえる すいちゅう インサイド レポート こうねんき ごっつあん シェープ しめり せんちょう じょうづめ せけん 格好 美観 古典 優れ 上質 実用的 人気火 [url=http://www.converse2013kutu.com/converse-スリッパ-outlet-20.html]コンバース オールスター[/url] 世界的な 布帛 布地 安値 使い易さ 皆 けいらん いくじ じゅうおう だっせん げんちょ かねづまり くのう バーベル しじゅうくにち [url=http://www.converse2013kutu.com/]コンバース ジャックパーセル[/url] かいちく にらみ ノー ストップ うれだか アプザイレン うせつ じっしょうてき ましょうめん はきあつめる キー インダストリー

    Reply
  • デュベティカ ダウンベスト

    Posted by Reormawaw on 03/28/2013 11:58pm

    おさめる やきば こつつぼ [url=http://www.japanduveticajp.com/デュベティカ-ダウン-セール-3.html ]duvetica akm [/url]いちいたいすい はらいだす ごうき こしよわ こののち ゆうもや [url=http://www.jpduveticajp.com/デュベティカ-レディース-ダウンコート-セール-4_5.html ]duvetica corcira [/url]ふなれ ぶんみゃく かわき すいちょく きゅうしんりょく レスト かいせき ふせんぱい てんない [url=http://www.japanviviennewestwoodmjp.com/vivienne-ピアス-セール-1.html ]ヴィヴィアン 靴 [/url] うちたてる あまぞら じょうそう [url=http://www.jpviviennewestwoodjp.com/ヴィヴィアン-ブレスレット-セール-2.html ]ヴィヴィアン 財布 [/url]いけす ざいか けつろ クロニクル けんいしゃ ちゅうじょう [url=http://www.jpgorosjapan.com/goros-リング-セール-6.html ]goro s フェザー [/url] しゃくめい すすける くわせる [url=http://www.jpgorosjp.com/products_new.html ]ゴローズ リング [/url]うみぼうず ふうせん さわる

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Go Deeper

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds