Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is memory allocated using alloca freed for class members?

class MyString
{
  public:
  MyString(int length):_ptr(alloca(length))
  {
  }
  //Copy Constructor, destructor, other member functions.
  private:
  void* _ptr;
};

int main()
{
  MyString str(44);
  return 0;
}

Is it freed at the end of the main function or immediately after constructor is executed? Is it a good idea to have a string class like this if the above code works as expected?

Update:

It looks like the main danger is

  1. StackOverflow
  2. Inlining of Constructor

I think I can take care of StackOverflow by using alloca for small sizes and malloc/free for large sizes. I guess there must be some non-portable compiler specific way to force the compiler to inline.

I am interested because string class is something that is widely used in any c++ project. If I get this right, I am expecting a huge performance gain as most of the allocations go inside stack which would go into heap otherwise. This will be a utility and the end user will not be aware of the internals.

like image 278
balki Avatar asked Jan 23 '26 07:01

balki


2 Answers

According to the documentation of alloca, the memory is freed when the caller of alloca returns. So, the memory will be freed at the end of the constructor if the initialiser list is considered as part of the constructor by the compiler, i.e. the stack frame is created before the initialise list is executed. If the stack frame is created after the initialiser list is executed, then the allocated memory will be in the caller of the constructor and so, in this case, the memory is freed at the end of main. I don't know the standard enough to be absolutely certain which way it'll happen.

However, the value of ptr will be unchanged whenever the memory is finally freed.

like image 79
Skizz Avatar answered Jan 24 '26 21:01

Skizz


Definitely the initialization of the class members are executed as a part of the c'tor. So, at least by standard, the validity of the pointer returned by alloca is limited to the c'tor.

So it seems a really bad idea to initialize your class members the way you do.

OTOH there will be no problem with the following:

class MyString
{
  public:
  MyString(void* ptr):_ptr(ptr)
  {
  }
  //Copy Constructor, destructor, other member functions.
  private:
  void* _ptr;
};

int main()
{
  MyString str(alloca(44));
  return 0;
}
like image 30
valdo Avatar answered Jan 24 '26 22:01

valdo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!