对齐的成员变量和动态分配
Aligned member variables and dynamic allocation
所以基本上,这就是我到目前为止得到的。 我有一个mat4
类,它由__m128
组成,需要在 16 字节边界上对齐:
_MM_ALIGN16
class mat4
{
...
};
我有另一个类,它本身没有对齐,但包含一个mat4
.
class OtherClass
{
private:
mat4 matrix;
// Other data whose alignment doesn't really matter
...
};
我需要动态分配OtherClass
的实例,ala:
OtherClass* stuff = new OtherClass[n];
如何保证实例内的mat4
正确对齐,同时仍调用mat4
的构造函数?
我可以(并且通常更喜欢)使用 C++11 的功能,也许aligned_storage
是我正在寻找的? 在这种情况下,我将如何使用它?
您可以使用放置 new 将内存分配与对象创建分离:
/* Memory allocation */
#ifdef _MSC_VER
void *buffer = _aligned_malloc(n * sizeof(OtherClass), 16);
#else
void *buffer = memalign(16, n * sizeof(OtherClass));
#endif
/* Object construction */
OtherClass *array = new (buffer) OtherClass[n];
/* Use your objects */
...
/* Object destruction */
for (size_t i = 0; i < n; i++) {
array[i].~OtherClass();
}
/* Memory deallocation */
#ifdef _MSC_VER
_aligned_free(buffer);
buffer = nullptr;
#else
free(buffer);
buffer = nullptr;
#endif
一种更C++的方法是使用 std::vector 和一个对齐的分配器。
您可以使用 std::aligned_storage
来定义具有指定对齐方式的未初始化存储以及放置 new 运算符。
例如:
class OtherClass
{
private:
using storage_t = typename std::aligned_storage<sizeof(mat4), 16>::type;
storage_t _storage;
mat4* address() {
return static_cast<mat4*>(static_cast<void*>(&_storage));
}
mat4 const* address() const {
return static_cast<mat4 const*>(static_cast<void const*>(&_storage));
}
public:
OtherClass() {
new(address()) mat4();
}
OtherClass(OtherClass const& rhs) {
new(address()) mat4(*rhs.address());
}
OtherClass& operator=(OtherClass const& rhs) {
*address() = *rhs.address();
}
~OtherClass() {
address()->~mat4();
}
// setter
template<typename... Args,
class Enable = typename std::enable_if<
std::is_constructible<mat4, Args...>::value
>::type
>
void setMat(Args&&... args) {
new(address()) mat4(std::forward<Args>(args) ...);
}
// getter
mat4 const& getMat() const {
return *address();
}
mat4& getMat() {
return *address();
}
...
};
另请参阅: 标准::aligned_storage
关于 SO 的类似问题:C++为对象分配存储而不初始化它?
union alignas (16) { __m128 _v; float _s[4]; };
-例如,关于严格混叠的通常警告 - 不能保证堆存储对齐。
您可以通过查询 std::max_align_t 类型来避免新的/删除实现,如本答案中所述。
否则,可能需要重新实现全局运算符new/delete函数。我认为每类方法是不够的。例如,考虑具有mat4
成员的类Camera
;如果在堆栈上实例化了Camera
,则应保留mat4
成员对齐方式。如果在堆上创建了一个Camera
对象,我看不出如何以其他方式强制执行。
相关文章:
- 动态分配Q_Property变量
- 在C++中动态分配变量类型
- 为什么动态分配的两个变量的内存位置不是连续的?
- C :动态分配的变量未在clang中删除
- 在 CPP 中动态分配变量的数据类型
- 结构变量的动态分配
- 在使用动态分配的变量和_chdir Windows功能时损坏的堆
- 如果我将内存动态分配给静态变量,我应该释放它还是会自动释放它
- 动态分配的成员变量。有什么意义?
- 对齐的成员变量和动态分配
- 动态分配的静态变量
- 尝试使用成员函数访问动态分配的成员变量时读取访问冲突
- 对于数据成员,如果包含对象已在动态内存中,则动态分配此变量(或不动态分配)之间是否有任何区别
- 如何为字符串数组实例变量动态分配空间
- 对动态分配的变量的引用与指向相同动态分配变量的指针
- C++动态内存分配.将动态分配的 char* 返回变量数组分配给 char 变量
- 在 c++ 中声明变量与动态为变量分配内存
- c++动态分配变量,执行的流程是什么
- 在C++解释器中动态分配变量的最佳方式
- 动态分配变量的作用域