【发布时间】:2014-12-04 03:52:33
【问题描述】:
我正在编写一个程序,我需要计算结构元素的两个地址之间的差异。对不起,如果不清楚,有些代码可能更明确。
代码中有一些 MPI 元素,但这不是我的问题。
typedef struct Str {
std::vector<int> itab;
std::vector<char> ctab;
} s_str;
int main(int argc, char **argv)
{
s_str *struc1 = new s_str();
MPI_Datatype Strtype;
int count = 2;
int lengths[2] = { 8, 8 };
MPI_Aint disp[2];
disp[0] = &struc1->itab - &struc1;
disp[1] = &struc1->ctab - &struc1;
MPI_Datatype types[2] = { MPI_INT, MPI_CHAR };
MPI_Type_create_struct(count, lengths, disp, types, &Strtype);
MPI_Type_commit(&Strtype);
(...)
}
问题发生在以下几行:
MPI_Aint disp[2];
disp[0] = &struc1->itab - &struc1;
disp[1] = &struc1->ctab - &struc1;
首先,MPI_Aint 是“包含任何有效地址的 C 类型”(取自文档)。我在这里尝试做的是计算 struc1->itab 和 struc1 地址之间的差异。
这是我遇到的错误:
tmp2.cpp: In function ‘int main(int, char**)’:
tmp2.cpp:30:30: erreur: invalid operands of types ‘std::vector<int>*’ and ‘s_str** {aka Str**}’ to binary ‘operator-’
tmp2.cpp:31:30: erreur: invalid operands of types ‘std::vector<char>*’ and ‘s_str** {aka Str**}’ to binary ‘operator-’
我想我没有正确访问地址,因为这里涉及的类型是std::vector<int>* 和s_str**。正确的方法是什么?
更多详细信息:我需要使用 MPI-I/O 将其写入文件。它告诉 MPI 每个 proc 需要多少空间来编写其整个数据集。所以基本上,我只想使用 MPI-I/O 将用户定义结构的内容写入文件中。原因如下。
【问题讨论】:
-
由于
struc1已经是一个地址(一个指针),通过在它上面使用address-of操作符你得到地址的地址(即一个指向指针)。如果你通过使用例如“修复”它&struc1->itab - struc1然后你没有得到地址,你得到了结构内itab成员的偏移量,已经有一个标准的offsetof宏。 -
哦,即使使用“修复”(即不使用结构的地址运算符),您仍然可能会遇到错误,因为类型并不真正兼容,您必须强制转换指针。或者,如果您想要获取偏移量,请使用
offsetof宏。 -
@JoachimPileborg
offsetof是 UB,除非该类是标准布局 - 并且std::vector可能不是标准布局,在这种情况下Str也不是。 -
请注意,即使您可以通过强制转换为 void* 来获取向量的地址,向量的实际元素也会放在内存中的其他位置*
-
如果您在 C++ 中使用 MPI,请考虑使用 Boost.MPI 之类的东西,它会为您处理所有这些讨厌的序列化问题。