【问题标题】:Is there a way to check if a memory address is between two other addresses?有没有办法检查内存地址是否在其他两个地址之间?
【发布时间】:2022-01-14 15:21:52
【问题描述】:

假设,“假设”,我有这个代码:

//two separate arrays of the same object that for the purposes of this question we will assume are not adjacent in memory
ObjectName* m_objects0 = new ObjectName[10];
ObjectName* m_objects1 = new ObjectName[10];

//and a pointer to a single object
ObjectName* m_pObject = nullptr;

如果我想遍历m_objects0 中的每个对象直到我到达末尾,然后“跳转”到m_objects1 的开头来遍历它,我将如何检查m_pObject 的地址是否位于任一数组的起始地址和结束地址? (我唯一的信息是每个数组的开始和结束地址)这是否可行?

我能想到的唯一方法是将地址转换为int

【问题讨论】:

  • 除相等/不等外,您只能将指针与指向同一数组中的元素或同一类的成员的指针进行比较。因此,您的比较要么显示指针在数组的范围内,要么它具有 UB。您可以将指针与其中一个数组中的每个元素进行比较,但这似乎效率不高。
  • 您要实现的高级目标是什么?这听起来像XY Problem
  • 另外,你为什么要比较低级的东西,比如指针地址?一个好的设计比较对象的某些属性是否相同或是否存在于对象容器中,而不是显式比较指针地址以查看该地址是否“落在”两个地址之间。
  • “我如何检查m_pObject 的地址是否位于任一数组的起始地址和结束地址之间” 它不是,因为它是空的。或者不是,因为它是一个局部变量。取决于您所说的“m_pObject 地址”的含义。这种“假设”场景可能会混淆您要解决的实际问题。
  • 你不能。指针上的 <<=>>= 运算符具有未定义的行为,除非两个指针都指向同一数组的元素或同一结构的成员。您最多可以检查m_pObject 是指向m_objects0 的元素还是指向m_objects1 的元素。如果它没有指向任何一个元素,那就是它 - 没有办法(不调用未定义的行为)来测试它是否指向你的数组“之间”、它们两个“之前”或两者“之后”他们。

标签: c++ pointers iteration memory-address


【解决方案1】:

您可以使用==!= 运算符检查给定指针是否(in)等于任何其他指针。

但是,您可以检查给定指针是否为<(=)>(=) 另一个指针当两个指针都指向同一个对象/数组时,否则行为未定义。 p>

因此,虽然m_pObject 指向m_objects0 中的元素,但您无法使用地址范围检查它是否(不)指向m_objects1 中的元素。

但是,您可以这样做:

ObjectName* m_objects0 = new ObjectName[10];
ObjectName* m_objects1 = new ObjectName[10];

...

ObjectName* object_ptrs[] = {
    m_objects0, m_objects0 + 10,
    m_objects1, m_objects1 + 10
};

for(int i = 0; i < 4; i += 2)
{
    ObjectName* m_pObject = object_ptrs[i];
    ObjectName* m_pObjects_end = object_ptrs[i+1];

    while (m_pObject != m_pObjects_end)
    {
        ...
        ++m_pObject;
    }
}

...

Online Demo

其中,您可以使用以下方法进一步概括(即,如果您需要 2 个以上的数组):

#include <vector>
#include <utility>

ObjectName* m_objects0 = new ObjectName[10];
ObjectName* m_objects1 = new ObjectName[10];
...

std::vector<std::pair<ObjectName*,ObjectName*>> object_ptrs;
object_ptrs.emplace_back(m_objects0, m_objects0 + 10);
object_ptrs.emplace_back(m_objects1, m_objects1 + 10);
...

for(auto &p : object_ptrs)
{
    ObjectName* m_pObject = p.first;
    ObjectName* m_pObjects_end = p.second;

    while (m_pObject != m_pObjects_end)
    {
        ...
        ++m_pObject;
    }
}

...

Online Demo

【讨论】:

    猜你喜欢
    • 2021-09-01
    • 1970-01-01
    • 2010-11-20
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-16
    • 2017-01-29
    相关资源
    最近更新 更多