何时使用 alloca 为类成员释放内存分配?

发布于 2024-12-13 09:31:06 字数 600 浏览 0 评论 0原文

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;
}

它是在主函数结束时释放还是在构造函数执行后立即释放? 如果上面的代码按预期工作,那么拥有这样的字符串类是个好主意吗?

更新:

看起来主要的危险是

  1. StackOverflow
  2. 构造函数的

内联,我想我可以通过使用 alloca 小尺寸和 malloc/free 大尺寸来处理 StackOverflow。我想一定有一些不可移植编译器特定的方法来强制编译器内联。

我很感兴趣,因为字符串类在任何 C++ 项目中都广泛使用。如果我做对了,我预计会有巨大的性能提升,因为大多数分配都会进入堆栈,否则会进入堆。这将是一个实用程序,最终用户将不知道其内部结构。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

牵你的手,一向走下去 2024-12-20 09:31:06

根据alloca的文档,当alloca的调用者返回时,内存被释放。因此,如果编译器将初始化列表视为构造函数的一部分,即在执行初始化列表之前创建堆栈帧,则将在构造函数结束时释放内存。如果在执行初始化列表之后创建堆栈帧,则分配的内存将位于构造函数的调用方中,因此在这种情况下,内存将在 main 结束时释放。我对标准的了解还不足以绝对确定它会以哪种方式发生。

但是,无论何时最终释放内存,ptr 的值都将保持不变。

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.

年少掌心 2024-12-20 09:31:06

当然,类成员的初始化是作为 c'tor 的一部分执行的。因此,至少按照标准,alloca 返回的指针的有效性仅限于 c'tor。

因此,按照您的方式初始化类成员似乎是一个非常糟糕的主意。

OTOH 以下情况不会有问题:

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;
}

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文