- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
在回答 https://stackoverflow.com/a/704568/8157187 中,引用了 Stroustrup 的一句话:
C++ explicitly allows an implementation of delete to zero out an lvalue operand, and I had hoped that implementations would do that, but that idea doesn't seem to have become popular with implementers.
但是,我没有在标准中找到这个明确的声明。当前标准草案 (N4659) 的一部分可以这样解释:
6.7:
When the end of the duration of a region of storage is reached, the values of all pointers representing the address of any part of that region of storage become invalid pointer values (6.9.2). Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior. Any other use of an invalid pointer value has implementation-defined behavior.
Footnote: Some implementations might define that copying an invalid pointer value causes a system-generated runtime fault
所以,在 delete ptr;
之后,ptr
的值变成了一个无效的指针值,并且使用这个值具有实现定义的行为。但是,并没有说ptr
的值是可以改变的。
这可能是一个哲学问题,如果一个人不能使用它的值,怎么能确定一个值发生了变化?
6.9:
For any object (other than a base-class subobject) of trivially copyable type T, whether or not the object holds a valid value of type T, the underlying bytes (4.4) making up the object can be copied into an array of char, unsigned char, or std::byte (21.2.1).43 If the content of that array is copied back into the object, the object shall subsequently hold its original value.
看来,将无效指针值 memcpy
放入 char 数组是有效的(取决于哪个语句“更强”,6.7 或 6.9。对我来说,6.9 似乎更强) .
这样,我可以检测到指针值已被 delete
更改: memcpy
delete
之前和之后的指针值到 char 数组,然后比较它们。
因此,据我了解,6.7 不允许 delete
修改其参数。
delete是否允许修改其参数?
在此处查看评论: https://stackoverflow.com/a/45142972/8157187
这是一个不太可能但仍然可能的实际代码,这很重要:
SomeObject *o = ...; // We have a SomeObject
// This SomeObject is registered into someHashtable, with its memory address
// The hashtable interface is C-like, it handles opaque keys (variable length unsigned char arrays)
delete o;
unsigned char key[sizeof(o)];
memcpy(key, &o, sizeof(o)); // Is this line OK? Is its behavior implementation defined?
someHashtable.remove(key, sizeof(key)); // Remove o from the hashtable
当然,这个片段可以重新排序,所以它成为一个肯定有效的代码。但问题是:这是一个有效的代码吗?
这是一个相关的思路:假设一个实现确实定义了脚注描述的内容:
copying an invalid pointer value causes a system-generated runtime fault
6.9 保证我可以 memcpy()
任何值。甚至是无效的。所以在这个理论实现中,当我 memcpy()
无效的指针值(应该成功,6.9 保证)时,从某种意义上说,我不使用无效的指针值,而只使用它的底层字节(因为它会产生运行时错误,而 6.9 不允许这样做),因此 6.7 不适用。
最佳答案
在删除之前,ptr
的值是有效的。删除后,该值无效。因此值(value)发生了变化。有效值和无效值是互斥的——一个值不能同时有效和无效。
你的问题有一个基本的误解;您将这两个不同的概念混为一谈:
这两件事之间没有一一对应的关系。同一个值可能有多种表示,同一个表示可能对应不同的值。
我认为你的问题的要点是:可以delete ptr;
改变ptr
的表示吗?。答案是"is"。您可以将已删除的指针 memcpy 到 char 数组中,检查字节,并发现它们都是零值字节(或其他任何字节)。这在 C++14 [basic.stc.dynamic.deallocation]/4(或 C++17 [basic.stc]/4)的标准中有所涵盖:
Any other use of an invalid pointer value has implementation-defined behavior.
它是实现定义的,实现可以定义检查字节给出值为零的字节。
您的代码片段依赖于实现定义的行为。 “有效代码”不是标准使用的术语,但代码可能不会从哈希表中删除预期的项目。
正如 Stroustrup 所暗示的,这是一个有意的设计决定。一个示例用法是在 Debug模式下将已删除指针设置为特定表示的编译器,以便如果随后使用已删除指针,它可以引发运行时错误。 Here's an example该原则对未初始化指针的作用。
历史记录:在 C++11 中,这种情况是未定义,而不是实现定义的。因此,使用已删除指针的行为与使用未初始化指针的行为相同。在 C 语言中,释放内存被定义为将指向该内存的所有指针置于与未初始化指针相同的状态。
关于c++ - 是否允许删除修改其参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45149756/
前言: 有时候,一个数据库有多个帐号,包括数据库管理员,开发人员,运维支撑人员等,可能有很多帐号都有比较大的权限,例如DDL操作权限(创建,修改,删除存储过程,创建,修改,删除表等),账户多了,管理
这个问题已经有答案了: Condition variable deadlock (2 个回答) 已关闭 5 年前。 在研究多线程时,我编写了以下代码,但在屏幕上没有观察到输出。我在这里做错了什么?我期
复制代码 代码如下: <IfModule mod_rewrite.c> RewriteEngineOn RewriteBase/ #将www.zzvips.com跳转到www.zzv
复制代码 代码如下: <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / # 把 www.zzvips.com
复制代码 代码如下: Const T_GATEWAY = "1.1.1.1" '网关 Const T_NEWDNS1 = "2.2.2.2" 'DNS1
0. 修改索引 大文本字段支持排序 PUT http://localhost:9200/lrc_blog/_mapping //请求体 { "properties": { "title": { "t
仅 react 当状态发生变化时重新渲染 . 那么为什么我会直接看到我对真实 DOM 所做的更改呢? 我知道我正在修改真实的 DOM,但是当我根本没有改变状态时触发重新渲染的是什么。 import R
Xcode beta 5 推出 @FetchRequest对于 SwiftUI。 我有一个 View ,它有一个 @FetchRequest . NSFetchRequest是在管理器中创建的,该管理
关闭。这个问题需要更多 focused .它目前不接受答案。 想改进这个问题?更新问题,使其仅关注一个问题 editing this post . 7年前关闭。 Improve this questi
我有一个表达式[text][id]应替换为链接 text 解决方案是( id 是整数) $s = preg_replace("/\[([^\]]+)(\]*)\]\[([0-9]+)\]/","$1$
我在 repo 中有一个文件,我不想让任何人更新。 我能做什么? 最佳答案 你想要svn锁:http://www.linxit.de/svnbook/en/1.2/svn.ref.svn.c.lock
说我有项目 list 。我想导出到csv,但在此之前我想做一些计算/修改。 基本上,设置如下所示: PS C:\Files> gci Directory: C:\Files Mode
我有一个非常简单的问题 - 是否可以修改 Java API 的源代码,例如Junit,JABX ? 我知道这似乎是一个非常愚蠢的问题,但它一直困扰着我一段时间。 最佳答案 如果您可以掌握源代码,那么请
我有一个带有变量/列的小标题,其中包括不同形状的小标题列表。我想为其中一个变量中的每个(子)标题添加一个变量/列。 例如此类数据 library("tibble") aaa aaa # A tibb
我有几个菜单,可以在单击时向当前链接添加变量。这是一个例子: 1 2 3 x y z 我的问题是,如果我选择“y”2次,它会添加“&cord=y”2次。相反,我希望它替
我有两个项目:一个服务项目和一个服务安装程序项目。服务项目具有适合我的产品的装配信息。它包括公司信息和正确的服务名称。一旦服务实际安装,所有这些似乎都会被忽略。安装服务时,它使用在服务安装程序的ini
以下代码何时可能产生副作用? @some = map { s/xxx/y/; $_ } @some; perlcritic 将其解释为危险的,因为例如: @other = map { s/xxx/y/
我想知道以下哪种解决方案更好:我想修改一些 .class 文件,我意识到有两种方法可以做到这一点: 反编译.class文件,修改它,最后再次编译。 - 直接用十六进制编辑器修改。 谢谢 最佳答案 在这
这是我的按钮代码 onclick 我希望我的程序等待用户单击一个 JPanel,并且当用户单击 JPanel 时,它应该在控制台上打印其名称。 此按钮代码未显示输出 JPopupMenu popu
我正在使用一个具有“getName()”方法的特定 API。 getName() 返回一个字符串。是否可以修改该字符串? API 中不包含修饰符方法,并且 String getName() 返回的是私
我是一名优秀的程序员,十分优秀!