Memory allocators

Memory allocators

Hello everyone!

I was playing around whith the memory allocators provided by the library in order to understand better how to work with them. This is what I did:

class Number {
    private:
      int n;
    public:
      Number(): n(9){};
      Number( const int& i): n(i){};
      const int Num(void) const { return n; }
      void SetNum(int i) { n = i; }
};

static Number* AllocateNumber( const int n ) {
  Numero* num = (Number*)tbb::tbb_allocator().allocate(sizeof(Number)+n);
  num->SetNum( n );
  return num;
};

static void DeallocateNumber( Number* n ) {
  tbb::tbb_allocator().deallocate((int*)n,n->Num());
};

int main(){
  Number* one = AllocateNumber( 1 );
  // more things
  DeallocateNumber( one );
}

This works fine(I think) but then I tried this other thing:

class Real {
    private:
      int n;
      double r;
    public:
      Real(): n(9),r(500.50){};
      Real( const int& i, const double& j ): n(i),r(j){};
      const int Num(void) const { return n; }
      const double Real(void) const { return r; }
      void SetNum(int i) { n = i; }
      void SetReal(double j) {r = j; }
};

static Real* AllocateReal( const int n, const double r ) {
 Real* num = (Real*) tbb::tbb_allocator().allocate(sizeof(Real)+n+r);
 num->SetNum(n);
 num->SetReal;
 return num;
}

This fails since I'm passing two arguments to the allocator template. So my question is, how can I allocate a Real object with two data members( an int and a double)? Is something like the first AllocateNumber or a workaround is needed?

Thanks!

4 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Hello again.

I tried this:

static Real* AllocateReal( const int n, const double r ) {
 double n_ = (double) n;
 Real* num = (Real*) tbb::tbb_allocator().allocate(sizeof(Real)+n_+r);
 num->SetNum(n);
 num->SetReal;
}

static void DeallocateReal( Real* n) {
  tbb::tbb_allocator().deallocate((double*)n,n->Num());
  tbb::tbb_allocator().deallocate((double*)n,n->Real());
}

int main(){
  Real* r = AllocateReal( 7, 8.5 );
  std::cout << r->Num() << " & " << r->Real() << "n";
 DeallocateReal( r );
}

It compiles( with warnings ) and it works.
The warnings:

In function Real* AllocateReal(int, double):
var.cpp:54: warning: passing double for argument 1 to typename tbb::internal::allocator_type::value_type* tbb::tbb_allocator::allocate(size_t, const void*) [with T = double]
var.cpp: In function void DeallocateReal(Real*):
var.cpp:61: warning: passing double for argument 2 to void tbb::tbb_allocator::deallocate(typename tbb::internal::allocator_type::value_type*, size_t) [with T = double]
Is there any way to get rid of the warnings? And, am I doing this properly or is there a better way to allocate/deallocate the objects?

Thanks!

Best Reply

Please have a good look at the documentation to see what arguments to pass to allocate() (ignore "hint") and deallocate() (tbb::tbb_allocator is modeled after std::allocator, so you could also look there).

As with std::allocator, tbb_allocator::allocate() returns a region of memory sufficient to hold a specified number of the specified type of objects, but does not initialise it in any way. You may use tbb_allocator::construct(), or std::raw_storage_iterator, or std::uninitialized_copy, or std::uninitialized_fill, or std::uninitialized_fill_n, or any other way to place values there, unless you know that the object can be safely assigned, which seems to be the case here even with the nontrivial constructors. Similarly for deallocation.

Thanks Raf!
Solved!

Leave a Comment

Please sign in to add a comment. Not a member? Join today