PCL中自定义点类型My_Point的stride与offset如何确定?
关于PCL自定义点类型
My_Point的getMatrixXfMap步长及对齐问题 我希望使用PCL的getMatrixXfMap函数,但不清楚自定义点类型My_Point的stride(步长)是多少。自定义点类型定义如下:
struct My_Point { PCL_ADD_POINT4D; uint8_t direction; uint8_t type; uint8_t count; uint32_t row; uint32_t col; float intensity; uint8_t index; uint8_t value1; float value2; union { union { struct { uint8_t b; uint8_t g; uint8_t r; uint8_t _unused; }; float rgb; }; uint32_t rgba; }; EIGEN_MAKE_ALIGNED_OPERATOR_NEW // ensure proper alignment } EIGEN_ALIGN16;
我原以为有14个值,stride为14,但不确定union(联合体)会如何影响stride。此外,getMatrixXfMap的文档提示“PointT类型大多是对齐的,因此偏移量不连续”,这句话具体是什么含义?我该如何确定这些参数值?
核心解答
1. 联合体对步长的影响
联合体的大小由内部最大成员的尺寸决定,而非所有成员尺寸之和。你的嵌套联合体中,底层struct是4个uint8_t(共4字节),float rgb和uint32_t rgba也都是4字节,因此整个联合体仅占4字节,不会额外增加结构体总长度。
2. 计算My_Point的实际步长(字节数)
getMatrixXfMap的stride参数指从一个点的起始地址到下一个点起始地址的字节数,不是成员数量。计算时需考虑成员尺寸+内存对齐:
PCL_ADD_POINT4D:展开为float x, y, z; float _padding;,共16字节- 后续成员总尺寸:3(3个uint8_t)+8(2个uint32_t)+4(float intensity)+2(2个uint8_t)+4(float value2)+4(联合体)=25字节
- 基础总尺寸:16+25=41字节
- 因结构体标注
EIGEN_ALIGN16(强制16字节对齐),最终会被填充到48字节(下一个16的倍数),这就是实际stride。
注意:按成员数量计算stride是错误的,该参数要求传入字节数。
3. “对齐导致偏移量不连续”的含义
PCL点类型通过EIGEN_ALIGN16或编译器规则保证内存对齐,目的是让Eigen等库高效处理数据,这会带来两个结果:
- 成员间可能插入填充字节:比如3个
uint8_t后,为保证uint32_t row的4字节对齐,编译器会自动插入1字节填充,导致row的起始地址是4的倍数。 - 结构体总大小会被填充到对齐要求的倍数:最终成员的实际内存偏移不是简单的尺寸累加,即“偏移量不连续”。
4. 准确确定参数值的方法
编译时计算
用C++原生宏直接获取:
// 获取点类型的字节大小(即stride) size_t point_stride = sizeof(My_Point); // 获取某个成员的偏移量,比如intensity size_t intensity_offset = offsetof(My_Point, intensity);
运行时验证
打印相邻点的地址差:
My_Point p1, p2; size_t stride = reinterpret_cast<char*>(&p2) - reinterpret_cast<char*>(&p1); // 输出stride即可得到实际步长
查看编译器结构体布局
用编译器选项查看详细内存布局:
- GCC:添加
-fdump-class-hierarchy编译选项 - Clang:添加
-Xclang -fdump-record-layouts编译选项
输出结果会显示成员的偏移量、填充字节位置等细节。
5. getMatrixXfMap参数使用示例
如果要映射intensity成员,代码示例如下:
pcl::PointCloud<My_Point>::Ptr cloud = ...; // 将所有点的intensity映射为列向量 Eigen::Map<Eigen::MatrixXf> intensity_map( reinterpret_cast<float*>(&cloud->points[0].intensity), cloud->size(), 1, sizeof(My_Point) // 传入实际步长(字节数) );
内容的提问来源于stack exchange,提问作者Isaac Martinez personal
相关产品推荐
相关产品推荐

