创建结构体时,我经常使用结构体初始化将其归零:
struct MyStruct data = { 0 };
但是,我正在分配一个非常大的 (200mb) 结构,并且因为它有严格的对齐需求(使用 AVX 的数学库),我使用 _mm_alloc
分配它:
struct MyStruct* data = (struct MyStruct*)_mm_malloc( sizeof (struct MyStruct), 32 );
要将这个结构归零,memset
工作正常。但是,如果我尝试在此处使用结构体初始化,它会因分段错误而崩溃:
*data = (struct MyStruct) { 0 };
对于动态分配的结构,我这样做是否不当?或者是否有其他原因导致无法以这种方式初始化严格对齐的分配内存块?
答案 0 :(得分:4)
当你这样做时:
*data = (struct MyStruct) { 0 };
您正在使用复合文字,它在本地范围内创建一个临时对象。此类对象通常驻留在堆栈中,因此如果此对象的大小约为 200MB,您将使用此临时对象溢出堆栈。
使用 memset
是将此数组清零的最佳方法。
答案 1 :(得分:0)
这取决于编译器的智能程度。
#define SIZE (200*1024*1024)
struct st
{
int i[SIZE];
};
struct st *foo(void)
{
struct st *x = malloc(sizeof(*x));
*x = (struct st){0};
return x;
}
gcc
在堆栈上为复合文字分配内存。
clang
没有。
您需要假设在最坏的情况下,编译器会为其分配内存。
https://godbolt.org/z/P4jscoPaf
如果初始化比较复杂,在静态存储中创建复合字面量(可能是因为大小)