为什么要替换默认的新操作符和删除操作符? [英] Why would one replace default new and delete operators?

查看:133
本文介绍了为什么要替换默认的新操作符和删除操作符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么应该会替换默认操作符 new delete

$ b
$ b

这是重载新的和删除的延续非常有趣的C ++常见问题:

操作员重载



此常见问题的后续条目是:

delete code>运算符?




注意:答案是基于Scott Meyers的更有效的C ++ br>
(注意:这意味着要输入 Stack Overflow的C ++常见问题 。如果您想批评在此表单中提供常见问题解答的想法,请在meta上发布所有这一切将是做到这一点的地方。在 C ++聊天室中监控对该问题的答案,其中首先开始了常见问题解答,因此,您的答案很可能会由提出此想法的人阅读。)

解决方案

由于多种原因,可能会尝试替换 new delete / p>

检测使用错误:



有多种方式可能会导致 new delete 可能会导致未定义行为的可怕的野兽 内存泄漏
各自的示例如下:

上使用多个 delete 存储器&不在使用分配的内存上调用 delete

重载运算符 new 可以保留分配的地址列表,重载的操作符 delete 可以从列表中删除地址,那么很容易检测到这样的使用错误。



同样,各种编程错误可能导致数据溢出(写入已分配块的末尾)和 / strong>(在分配块开始之前写入)。

重载运算符 new 可以重新分配块并放入已知的字节模式签名)在客户端可用的存储器之前和之后。重载的操作符删除可以检查签名是否仍然完整。
因此,通过检查这些签名是否不完整,可以确定在所分配的块的生存期间的某个时间发生溢出或欠载,并且操作员删除可以记录该事实以及违规的值






提高效率(速度和记忆):



对于每个人来说, new delete 最适合没人。这种行为来自于它们仅被设计用于通用目的。它们必须适应分配模式,从在程序的持续时间存在的几个块的动态分配到大量短暂对象的常量分配和释放。最终,与编译器一起运行的运算符 new 和运算符 delete 采取中间的策略。 / p>

如果您对程序的动态内存使用模式有很好的理解,您通常可以发现运算符new和operator delete的自定义版本性能更好(性能更快,内存高达50%)默认值。当然,除非你确定你在做什么,这是不是一个好主意(如果你不理解涉及的复杂,甚至不要尝试这个)。






收集使用统计信息:



在考虑替换 new delete 以提高效率,如#2中所述,您应收集有关应用程序/程序如何使用动态分配的信息。您可能想要收集有关以下内容的信息:

分配块的分布,

生命周期的分布,

分配顺序(FIFO或LIFO或随机) br>
了解使用模式在一段时间内的更改,最大动态内存使用量等。



此外,有时您可能需要收集使用信息如:

计算类的动态对象数,

限制使用动态分配等创建的对象数。



全部,可以通过替换自定义删除并添加诊断收集机制重载删除






为了补偿 new 中的次优内存对齐:

许多计算机体系结构要求特定类型的数据被放置在特定类型的地址的存储器中。例如,体系结构可能需要指针出现在四的倍数的地址(即,四字节对齐),或者双倍必须出现在八的倍数的地址(即,八字节对齐)。不遵循此类约束可能会导致运行时的硬件异常。其他架构更宽容,并且可能允许它工作,虽然降低性能。与一些编译器一起运行的操作符 new 不保证动态$ b的八字节对齐$ b双重分配。在这种情况下,用保证八字节对齐的默认操作符 new 替换可能会大大提高程序性能,可以是替换删除运算符的良好理由。



如果您知道特定的数据结构通常一起使用,并且您想要在处理数据时最小化页面错误的频率,为数据结构创建一个单独的堆可能是有意义的,因此它们在尽可能少的页面上聚集在一起。 new delete 的自定义放置版本可以实现这样的聚类。






为了获得非常规的行为:



有时候你想让操作符new和delete来做编译器提供的版本不提供。

例如:您可以编写一个自定义运算符 delete ,用零替换被释放的内存,以增加应用程序数据的安全性。


Why should would one replace the default operator new and delete with a custom new and delete operators?

This is in continuation of Overloading new and delete in the immensely illuminating C++ FAQ:
Operator overloading.

An followup entry to this FAQ is:
How should I write ISO C++ standard conformant custom new and delete operators?

Note: The answer is based on lessons from Scott Meyers' More Effective C++.
(Note: This is meant to be an entry to Stack Overflow's C++ FAQ. If you want to critique the idea of providing an FAQ in this form, then the posting on meta that started all this would be the place to do that. Answers to that question are monitored in the C++ chatroom, where the FAQ idea started out in the first place, so your answer is very likely to get read by those who came up with the idea.)

解决方案

One may try to replace new and delete operators for a number of reasons, namely:

To Detect Usage Errors:

There are a number of ways in which incorrect usage of new and delete may lead to the dreaded beasts of Undefined Behavior & Memory leaks. Respective examples of each are:
Using more than one delete on newed memory & not calling delete on memory allocated using new.
An overloaded operator new can keep a list of allocated addresses and the overloaded operator delete can remove addresses from the list, then it is easy to detect such usage errors.

Similarly, a variety of programming mistakes can lead to data overruns(writing beyond the end of an allocated block) and underruns(writing prior to the beginning of an allocated block).
An Overloaded operator new can over-allocate blocks and put known byte patterns ("signatures") before and after the memory made available to clients. The overloaded operator deletes can check to see if the signatures are still intact. Thus by checking if these signatures are not intact it is possible to determine that an overrun or under-run occurred sometime during the life of the allocated block, and operator delete can log that fact, along with the value of the offending pointer, thus helping in providing a good diagnostic information.


To Improve Efficiency(speed & memory):

The new and delete operators work reasonably well for everybody, but optimally for nobody. This behavior arises from the fact that they are designed for general purpose use only. They have to accommodate allocation patterns ranging from the dynamic allocation of a few blocks that exist for the duration of the program to constant allocation and deallocation of a large number of short-lived objects. Eventually, the operator new and operator delete that ship with compilers take a middle-of-the-road strategy.

If you have a good understanding of your program's dynamic memory usage patterns, you can often find that custom versions of operator new and operator delete outperform (faster in performance, or require less memory up to 50%)the default ones. Of course, unless you are sure of what you are doing it is not a good idea to do this(don't even try this if you don't understand the intricacies involved).


To Collect Usage Statistics:

Before thinking of replacing new and delete for improving efficiency as mentioned in #2, You should gather information about how your application/program uses dynamic allocation. You may want to collect information about:
Distribution of allocation blocks,
Distribution of lifetimes,
Order of allocations(FIFO or LIFO or random),
Understanding usage patterns changes over a period of time,maximum amount of dynamic memory used etc.

Also, sometimes you may need to collect usage information such as:
Count the number of dynamically objects of a class,
Restrict the number of objects being created using dynamic allocation etc.

All, this information can be collected by replacing the custom new and delete and adding the diagnostic collection mechanism in the overloaded new and delete.


To compensate for suboptimal memory alignment in new:

Many computer architectures require that data of particular types be placed in memory at particular kinds of addresses. For example, an architecture might require that pointers occur at addresses that are a multiple of four (i.e., be four-byte aligned) or that doubles must occur at addresses that are a multiple of eight (i.e., be eight-byte aligned). Failure to follow such constraints can lead to hardware exceptions at run-time. Other architectures are more forgiving, and may allow it to work though reducing the performance.The operator new that ship with some compilers don't guarantee eight-byte alignment for dynamic allocations of doubles. In such cases, replacing the default operator new with one that guarantees eight-byte alignment could yield big increases in program performance & can be a good reason to replace new and delete operators.


To cluster related objects near one another:

If you know that particular data structures are generally used together and you'd like to minimize the frequency of page faults when working on the data, it can make sense to create a separate heap for the data structures so they are clustered together on as few pages as possible. custom Placement versions of new and delete can make it possible to achieve such clustering.


To obtain unconventional behavior:

Sometimes you want operators new and delete to do something that the compiler-provided versions don't offer.
For example: You might write a custom operator delete that overwrites deallocated memory with zeros in order to increase the security of application data.

这篇关于为什么要替换默认的新操作符和删除操作符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆