对运算符的调用是否'delete'同步的?
Is the call to operator 'delete' synchronous?
我想知道对操作符delete
的调用是否同步。换句话说,如果我这样做:
delete p;
c++标准是否保证只有在调用完成执行后内存才会被释放?或者调用是异步的,只是为操作系统调度一个任务,以便在它决定释放内存的最佳时机时立即释放内存?
如果第一种情况是有效的,那么是否意味着我们必须实现我们自己的异步删除工具?我问这个问题是因为我想说,大多数时候我们(程序员)并不关心内存何时被释放,因此我们不希望我们的代码冻结并等待这个(最可能昂贵的?)系统调用完成,而是安排一个删除任务并立即继续执行。c++是否提供了任何标准工具(也许是通过标准库?)来做到这一点,而无需重新发明轮子?
delete
为同步。现在,这并不意味着底层内存实际上在那个时候被操作系统释放了,但是从c++系统的角度来看,它的行为就像。
我问这个问题是因为我想说大多数时候我们(程序员)并不关心内存何时被释放
但是delete
主要不是关于内存的,它只是以确定性的方式调用析构函数——它是一种通用的资源释放机制,不局限于内存。在这里,具有同步性是很重要的,否则c++的一个核心方面——RAII——将无法工作。
不能保证delete p;
将内存释放回操作系统——永远不能。事实上,在相当多的(大多数?)实现中,它不会做任何这样的事情。
delete
时,究竟发生了多少,但在某些情况下,它几乎是即时的(只是将块链接到空闲内存块列表)。在其他情况下,它做了更多的工作:销毁对象,可能还在当前空闲列表中搜索可以与被释放的块合并的相邻块。
就您所关心的而言,一切都完全按照您的期望运行,并且没有隐藏的陷阱或陷阱。你总是可以说T * p = new T; delete p;
,这是正确的,无论在什么上下文中。
考虑到操作系统通常必须并发地为各种进程和线程分配内存,您可以假设这个问题已经被正确地解决了。
更正式地说,18.6.1.4/1 ("Data Races")说:
为了确定是否存在数据竞争,
operator new
的库版本,全局operator new
的用户替换版本,以及C标准库函数calloc
和malloc
应该表现得好像它们只访问和修改了返回值所引用的存储。库版本operator delete
的,operator delete
的用户替换版本,以及C标准库函数free
的行为应该表现得好像它们只访问和修改了它们的第一个参数所引用的存储。
关于"阻塞":这一切都归结为C库的分配函数所做的。除了"此函数返回指向某些内存的指针"之外,没有指定任何内容。这取决于平台如何提供内存分配。
C/c++中的自由调用已经非常快了。在这方面,你没有理由拖延到更合适的时候才删除它。你为此需要做的任何簿记都将超过实际的免费通话时间。
如果你的析构函数做更多的工作,比如关闭DB连接的套接字,那么你可以在以后的时间做这种工作,但这应该是一种例外情况。
- 运算符C++ "delete []"仅删除 2 个前值
- 松弛原子与无同步情况下的记忆连贯性
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- g++用户定义的动态链接库上的全局new和delete运算符
- 在C++中同步线程
- 与 stdio 同步是否使程序 I/O 非交互式?
- 为什么"delete"关键字不删除节点?
- 如何在qt中同步应用程序和显示器的刷新率?
- Windows 进程间同步类似事件?
- "delete"在 C++ 中实际上做了什么?
- 析构函数和'delete'之间的区别
- 如何知道何时调用删除以及何时调用 delete[] C++?
- 在对象指针上调用 Delete 是否会递归删除其动态分配的成员
- 体系结构x86_64的未定义符号:std:terminate(),typeinfo,运算符delete[],运算符new
- 当对套接字 send() 的同步调用由于连接另一端丢失而被阻止时,如何恢复?
- 析构函数中的"delete this"
- 为什么数组大小信息可用于"sizeof"运算符和 delete[] 运算符,但在将数组作为参数传递到
- 将 10 个线程与原子布尔值同步
- 即使在使用 delete[] 后仍保留的元素
- 对运算符的调用是否'delete'同步的?