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

Struct initialization of allocated block causing Segmentation Fault

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

struct MyStruct data = { 0 };

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

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

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

*data = (struct MyStruct) { 0 };

我是否为动态分配的结构不正确地执行了此操作?还是有其他原因导致无法以这种方式初始化严格对齐的分配内存块?

当你这样做时:

*data = (struct MyStruct) { 0 };

您正在使用 复合文字,它在本地范围内创建一个临时对象。这样的对象通常驻留在堆栈中,因此如果该对象的大小约为 200MB,您将使用该临时对象溢出堆栈。

使用 memset 是将该数组置零的最佳方法。

这取决于编译器的智能程度。

#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

如果初始化更复杂,clang 会将创建的复合文字放在静态存储中(可能是因为大小)

https://godbolt.org/z/bEbExWdEq