全局变量的内存布局
Memory layout of globals
>考虑
Foo data[]={{...},{...},{...}};
Foo data_end={...};
如果结束标记是在数组之后定义的,是否可以保证
&data[3]==&data_end
我不想手动计算数据中的元素数量。
它碰巧在没有任何优化选项的情况下在 gdb 中看起来不错,但在使用它之前,我需要知道编译器无法移动data_end
.如果可以,我该怎么做。
不仅不能保证您请求的内容,而且符合 C++03 的实现必须确保&data[3] != &data_end
:
5.10 相等运算符[expr.eq]
1 ...相同类型的两个指针比较相等,当且仅当它们都是 null,都指向同一个对象或函数,或者都指向同一数组末尾的一个。
在 C++11 中,它稍微复杂一些:
当且仅当两个相同类型的指针都为 null、都指向同一函数或都表示相同的地址 (3.9.2) 时,它们才相等。
3.9.2 注意事项:
。如果一个
T
类型的对象位于地址A
,则 cvT*
类型的指针的值是地址A
被称为指向该对象,而不管该值是如何获得的。[注意:例如,超过数组末尾的地址(5.7)将被视为指向数组元素类型的不相关对象,该对象可能位于该地址。
因此,新标准允许合规的实现在您的比较中产生真;仍然没有保证。
如果需要计算数组的元素数,请使用以下常用宏:
#define countof(ARR) (sizeof (ARR) / sizeof *(ARR))
或者,如果您不喜欢宏,请使用以下函数:
template<class T, std::size_t N>
constexpr std::size_t countof(T (&)[N])
{
return N;
}
但是,后一个选项需要编译器支持 constexpr
关键字才能与前者完全等效。
No.编译器以任何顺序或任何对齐方式放置变量并不是一个可靠的假设。变量之间可能存在对齐间隙,我已经看到按字母顺序对变量进行排序的编译器。
如果你想知道指向不在数组中的元素的指针,你需要知道数组元素的数量。
#define _dimof(a) (sizeof(a)/sizeof(a[0]))
Foo data[] = ... ;
// The type of the variable has been changed.
Foo* data_end = &data[_dimof(data)];
您可以删除此段落,因为它是为了修复代码中的语法错误而添加的。
不,它不可靠,在 C++11 中,只需执行
for (/* const */ Foo& foo : data) {
// stuff with foo.
}
- 将布局映射到内存地址
- C++继承的虚拟类的内存布局
- 检查nullptr是否100%保护内存布局不受segfault影响
- C++ Python 的扩展 - 安全内存访问和内存布局
- 类似元组的类模板的反向内存布局
- 在C++标准中记录对象的内存布局的哪个位置?
- C++ Lambda 的内存布局
- 打包类的内存布局 + 继承
- 假设传递给 OpenGL 的结构数组的内存布局存在潜在错误
- COM 互操作结构定义与内存布局不匹配
- C++非虚拟类成员变量内存布局?
- 结构中的内存布局差异
- 2D 区域的内存布局
- 如果"原子"<T>是无锁的并且与"T"的大小相同,内存布局是否相同?
- 是C 单继承的内存布局与此C代码相同
- 直观的内存布局,可实现快速SIMD/面向数据的设计
- 使用GDB并检查Data的内存布局
- 对齐方式究竟如何影响内存布局和新放置的巴哈维?
- 数组向量的内存布局是什么
- 为什么C 标准专门为具有不同访问说明符的类数据成员的内存布局提供了余地