【问题标题】:Which dummy pointer values are okay哪些虚拟指针值是可以的
【发布时间】:2015-05-06 17:40:17
【问题描述】:

这是我想了很久的事情。每隔一段时间,我就会看到人们使用 1 或 -1 作为指针的虚拟值。为了安全需要不同的变量。

可以使用这样的指针吗?我想-1没问题。但是也可以使用其他负数吗?我可以确定 1 不是已使用的内存位置吗?如果是这样,我可以使用内存指针达到哪个值。

附:我知道在指针中存储其他数据,尤其是正值,是非常非常糟糕的做法。但我只是想知道在任何现实生活中会有什么后果。

【问题讨论】:

标签: c++ pointers pointer-arithmetic


【解决方案1】:

我敢打赌,当您这样做时,您的编译器会发出警告?这本身就应该告诉你这是不好的,应该避免。

许多旧的硬壳代码都有针对值的 NULL(或 nullptr)的防护措施。你在其中放置一个 -1,它会变成一个无符号的 0xffffffff 地址(32 位域)到该指针中,它会愉快地运行各种你不希望它运行的东西。最好的情况是立即访问冲突/段错误。最坏的情况是没有人注意到,2 个月后事情变得异常,你被发现是一个,嗯......“不聪明的人”,他非法地将非指针值放入指针中并把事情搞砸了。此类错误可能会导致工作流失。

顺便说一句,“人们”为什么要在指针中使用 1 或 -1?删除 nullptr、NULL 或您的语言支持的任何内容并完成它。否则在里面放一个有效的指针并称之为好。

【讨论】:

  • 好吧,我的 2 美分将是一件“直觉”的事情。您用 nullptr 标记某些内容,那么为什么不使用 1 标记某些内容。我知道这是违规行为,脾气可能会上升。这就是为什么我在 p.s. 中覆盖自己:)。
  • 比起导致崩溃的意外疏忽,我更担心脾气和宗教战争。如果您绝对需要一个替代值,则创建一个名为 dummy 的全局指针,并将其设置为 null,或者让它指向一个在调用它时会导致断言的东西。
【解决方案2】:

您可以便携使用的唯一指针值是指向当前存在的对象的指针和空指针。 (我忽略了函数指针和成员指针。)

空指针的目的是获得一个不指向任何对象的指针值,并且它与任何指向对象的指针比较不相等。该语言只为每种指针类型提供一个这样的指针值。

有时拥有多个可区分的指针值会很方便。

您可以自己定义这些值——例如:

const some_type* foo = reinterpret_cast<some_type*>(-1);
const some_type* bar = reinterpret_cast<some_type*>(-2);

严格来说,使用任何一个值,即使没有取消引用它,也会有未定义的行为。 (我知道 C 就是这种情况;我认为 C++ 也是如此。)但是如果您碰巧知道这些值与指向实际对象的任何指针不同,并且与它们的比较行为符合预期,那么您可以摆脱它。

在 C 标准库中有一些这样的先例。 &lt;signal.h&gt; 为信号处理函数指针定义了三个宏,SIG_DFLSIG_ERRSIG_IGN。在一些实现中,这些被定义为将常量 -1、0 和 1 强制转换为适当的指针类型。这些定义是不可移植的——但由于它们是实现本身的一部分,它们不必是。唯一的要求是它们必须与任何指向用户定义函数的指针进行比较。 (在我使用的实现中,SIG_DFL 恰好是一个空指针;这不是必需的。)

如果库定义了这样的指针,请随意使用它。如果它失败了,那是库中的一个错误。如果您想自己定义这样的指针,请小心,并了解它可能无法在所有实现中正常工作。

另一种方法是定义适当类型的静态对象,并使用指向该对象的指针:

static some_type foo_obj;
static some_type bar_obj;
const some_type* foo = &foo_obj;
const some_type* bar = &bar_obj;

这是可移植的并且它给你的指针值保证不等于空指针和任何指向用户定义对象的指针。

【讨论】:

  • 我不清楚 C++ 中的这种情况,请参阅my comment above 以及该措辞来自的 DR。
【解决方案3】:

这取决于您的编译器和(主要是)操作系统——在大多数操作系统上,地址范围永远不会有效。因此,在这样的操作系统上,将这样的地址用作指针的“魔术”值是安全的,该指针永远不会与任何有效对象进行比较。只要您从不取消引用它们,它们就应该没问题 - 即使您确实取消引用它,操作系统也可能会定义行为(通常会引发特定信号)。

更便携的替代方法是创建“虚拟”全局对象并将指向它们的指针用作特殊标记。没有其他有效对象指针会与虚拟对象指针进行比较,并且虚拟对象的额外开销是最小的。

【讨论】:

  • 我同意这个答案。这样做很讨厌,但在大多数方面,您可以将指针视为 int 并且您会没事的。这样做是完全愚蠢的,但你可以做到:)。这是出现问题的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-20
  • 2021-06-22
  • 2012-06-08
相关资源
最近更新 更多