对重载new和delete施加限制

发布于 2024-10-18 22:36:21 字数 199 浏览 5 评论 0原文

是否可以对重载运算符 new 和 delete 施加一些限制? 我的重载 new 在另一个文件中链接到我的测试程序。

场景是:

if(condition is satisfied)
   call overloaded new
else
   call the actual new defined in new.h

Is it possible to put some restrictions in overloading operators new and delete?
My overloaded new is linked in a different file to my test program.

The scenario is:

if(condition is satisfied)
   call overloaded new
else
   call the actual new defined in new.h

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

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

发布评论

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

评论(4

野稚 2024-10-25 22:36:21

始终使用重载的new/delete并检查其实现中的条件。

Always use your overloaded new/delete and check your condition inside its implementation.

许仙没带伞 2024-10-25 22:36:21

一旦你替换了默认的 ::operator new() 你就不能再使用它了——它就永远消失了。 查看此问题

如果您想获得原始 ::operator new() 的效果,您必须重新实现它,这并不难。

Once you replace the default ::operator new() you can't use it anymore - it's gone forever. See this question.

If you want to have the effect of the original ::operator new() you'll have to reimplement it which isn't very hard.

纸伞微斜 2024-10-25 22:36:21

可以通过三种方式为运营商提供新的服务。

  • 替换四个非放置默认运算符 new 中的一个或多个,

  • 为默认运算符 new 提供重载(因此带有一个附加参数,这些可以使用placement new语法调用),

  • 提供operator new类成员,那些将仅为该类及其后代调用。

在后两种情况下,可以使用以下语法调用更知名的运算符 new 之一:

ptr = ::operator new(sz);
ptr = ::operator new[](sz);
ptr = ::operator new(sz, std::nothrow);
ptr = ::operator new[](sz, std::nothrow);

但如果您已替换它们,则将调用您的替换项。 您不能将已替换的默认运算符称为新的(也许您可以通过使用特定于实现的链接器技巧来实现,但这超出了语言的范围)。

关于operator new的替换:

  • 您应该将两个operator new和对应的两个operator delete一起替换(或者其中一个delete操作符很容易被非预期的指针调用)
  • 您应该替换两个operator new[]和对应的两个operator一起删除[](同样的原因)
  • 注意新处理程序的可能性,有些库会使用它。

There are three ways to provide an operator new.

  • replacing one or more of the four non placement default operators new,

  • providing overload to the default operator new (thus with an additional parameter, those may be called with the placement new syntax),

  • providing operator new class members, those will be called only for that class and their descendant.

In the latter two cases, it is possible to call one of the more well know operators new with the syntax:

ptr = ::operator new(sz);
ptr = ::operator new[](sz);
ptr = ::operator new(sz, std::nothrow);
ptr = ::operator new[](sz, std::nothrow);

but if you have replaced them, your replacement will be called. You can't call the default operators new you have replaced (well perhaps you can by playing implementation specific linker tricks, but that's outside the scope of the language).

About the replacement of operator new:

  • you should replace the two operators new and the corresponding two operator delete together (or one of the delete operator could be easily called with unexpected pointer)
  • you should replace the two operators new[] and the corresponding two operator delete[] together (same reason)
  • pay attention to what is possible with the new handlers, some library plays with that.
放手` 2024-10-25 22:36:21

您可以轻松地在重载的 new 运算符中执行检查。确保实现 new 运算符的所有风格(正如 AProgrammer 已经指出的那样)。

调用原来的/默认的new是不可能的,但是自己实现也不难。毕竟new只是分配内存而已。因此,您也可以调用 malloc、HeapAlloc 或系统上找到的任何内存分配例程,而不是调用原始/默认的 new。请务必在删除的实现中调用相应的内存释放方法(free、HeapFree,...)。

你没有告诉你要在 new 的实现中检查什么样的条件?如果它是“静态”条件(我的意思是:在应用程序执行期间始终给出相同的结果),则还应该将相同的条件添加到删除的实现中。

如果条件取决于情况并在运行应用程序时发生变化,您应该预见一种方法,您可以通过该方法知道在删除函数中使用哪个删除实现。对此的一个技巧如下:

在 new 的实现中:

  • 分配比请求多 8 个字节(这必须是 8 个字节以保持对齐正确)
  • 用标识填充前 8 个字节,以便您可以知道哪个底层内存-您使用的分配函数
  • 将 8 个字节添加到分配的指针并返回这个

在您的删除实现中:

  • 减去给定的指针的 8 个字节,
  • 检查在该位置找到的标识(请参阅新的)以查看哪种底层删除-你应该调用的实现

You can easily perform the check in your overloaded new operator. Be sure to implement all flavours of the new operator (as AProgrammer already pointed out).

Calling the original/default new is not possible, but it's not difficult to implement it yourself. After all, new only allocates memory, that's it. So instead of calling the original/default new, you can also call malloc, HeapAlloc, or any memory-allocation routine found on your system. Be sure to call the corresponding memory-deallocation method (free, HeapFree, ...) in your implementation of delete.

You didn't tell what kind of condition you are going to check in your implementation of new? If it's a 'static' condition (I mean: always giving the same result during the execution of your application), the same condition should also be added to your implementation of delete.

If the condition depends on the situation and changes while running your application, you should foresee a method where you can know which delete implementation to use in your delete function. One trick do to this is the following:

In your implementation of new:

  • allocate 8 bytes more than requested (this must be 8 bytes to keep the alignment correct)
  • fill in the first 8 bytes with an identification so that you can know which underlying memory-allocation function you used
  • add 8 bytes to the allocated pointer and return this one

In your implementation of delete:

  • subtract 8 bytes of the pointer given to you
  • check the identification found at that place (see new) to see which kind of underlying delete-implementation you should call
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文