分配块的结构初始化导致分段错误
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 会将创建的复合文字放在静态存储中(可能是因为大小)
创建结构时,我经常使用结构初始化将其归零:
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 会将创建的复合文字放在静态存储中(可能是因为大小)