已分配块的结构初始化导致分段错误

时间:2021-04-08 15:10:22

标签: c c11

创建结构体时,我经常使用结构体初始化将其归零:

struct MyStruct data = { 0 };

但是,我正在分配一个非常大的 (200mb) 结构,并且因为它有严格的对齐需求(使用 AVX 的数学库),我使用 _mm_alloc 分配它:

struct MyStruct* data = (struct MyStruct*)_mm_malloc( sizeof (struct MyStruct), 32 );

要将这个结构归零,memset 工作正常。但是,如果我尝试在此处使用结构体初始化,它会因分段错误而崩溃:

*data = (struct MyStruct) { 0 };

对于动态分配的结构,我这样做是否不当?或者是否有其他原因导致无法以这种方式初始化严格对齐的分配内存块?

2 个答案:

答案 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

如果初始化比较复杂,在静态存储中创建复合字面量(可能是因为大小)

https://godbolt.org/z/bEbExWdEq