【问题标题】:How to dereference typedef array pointer properly?如何正确取消引用 typedef 数组指针?
【发布时间】:2017-06-15 19:19:16
【问题描述】:

我正在使用第 3 方代码,其类型定义为:

typedef float MarkerData[3];  

稍后在代码中,我将此标记位置数据的数组引用为:

MarkerData* Markers;    

我正在使用这段代码来迭代这个数组:

for (int32 s = 0; s < totalMarkers; s++)
{

MarkerData* mData = (Markers + s);

markerPosition.X = *(mData)[0];
markerPosition.Y = *(mData)[1];
markerPosition.Z = *(mData)[2];


}

代码不会崩溃,但浮点值会混在一起。从调试中我可以看到,我在每次迭代中都正确获得了 markerPosition.X 值,但 Z 和 Y 是从其他数组中获取的。我想我在这里使用了错误的指针算术,但无论如何,都无法弄清楚。这个 typedef 对我来说真的很新,我不知道 - 可能有什么问题?

【问题讨论】:

  • int32 s = 0; 应该是size_t s = 0;
  • @πάνταῥεῖ 这值得商榷,可能取决于totalMarkers 的类型。
  • totalMarkers 类型为 int32
  • 您能否提供minimal reproducible example 以及您获得的结果与您预期的结果之间的比较?用这么少的信息很难明确知道你做错了什么。
  • 强烈怀疑您打算将*(mData)[0] 的格式设置为(*mData)[0]。并且“不崩溃”绝不应该等同于“正确”。通过 Valgrind 运行它可能标记读取违规。

标签: c++ pointer-arithmetic


【解决方案1】:

这是对Operator Precedence的误解导致的错误。运算符具有应用它们的顺序。这类似于数学中的运算符优先级,例如,乘法的优先级高于加法。 operator*(解引用运算符)的优先级低于operator[](下标运算符)。这意味着表达式*(mData)[2] 被解析为“取消引用指针mData 处的第三个元素”。第三个元素大概是一个包含 3 个浮点数的数组(如果您没有超出 mData 指向的数组的边界)。然后,您取消引用该结果数组。取消引用数组会为您提供该数组中的第一个元素。本质上,您是一次又一次地获取不同标记的第一个元素。您可以使用括号更改优先级。请改用(*mData)[0]。这将首先强制取消引用您的指针,为您提供 floats 数组,然后使用下标运算符通过索引访问该数组。

for (int32 s = 0; s < totalMarkers; s++)
{
    MarkerData* mData = (Markers + s);

    markerPosition.X = (*mData)[0];
    markerPosition.Y = (*mData)[1];
    markerPosition.Z = (*mData)[2];
}

使用适当的 c++ 容器(例如 std::arraystd::vector)可以避免大部分麻烦。

【讨论】:

  • 不,误解不仅仅是制表符优先级。有一种误解是,(mData) 中的括号与 mData 的作用不同(在普通情况下,mData 不是一个表现不佳的宏)。
猜你喜欢
  • 2019-03-11
  • 2022-11-21
  • 2017-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-25
  • 2011-10-20
  • 1970-01-01
相关资源
最近更新 更多