关于C#:有没有办法保证malloc() – ed结构成员的对齐

Is there a way to guarantee alignment of members of a malloc()-ed structs

我最近修复了一个bug,其中一个结构的__declspec(align(64))成员由于该结构的内存分配方式而未对齐。所以,我正在寻找一种解决这种情况的方法。

例如,考虑以下结构:

1
2
3
4
struct foo {
    __declspec(align(64)) int bar[BAZ_LEN];
    int baz;
};

如果在堆栈上分配,编译器将负责对齐。如果通过malloc()分配,它将不起作用。如果由于性能或正确性(或两者)的原因而依赖于条形码的对齐,那么这将破坏访问条形码的代码。

所以,问题是:处理这种情况的最佳方法是什么?在我的情况下,除了我的组件的"私有"功能之外,struct foo可以被认为是不透明的。

澄清/更新。非常感谢你的回答。我应该事先说过,但问题是我的结构的用户分配了一块内存并将其分割成多个块,中间的一个是foo_t结构的数组。该数组的偏移量不是常量,因此对齐起始地址可能没有帮助。我正在寻找一种方法来允许这样使用我的结构,同时保留一些对齐假设。

我现在想到的解决方案(还没有尝试过)是添加填充成员:

1
2
3
4
5
struct foo {
    __declspec(align(64)) int bar[BAZ_LEN];
    int baz;
    char padding[64];
};

比在每个函数中执行以下操作(包装在宏中):

1
2
3
4
5
void f(foo_t *foo_)
{
    foo_t *foo = (foo_t *)(((uintptr_t)foo_ & ~63) + 64);
    ...
}

这会浪费每个结构64个字节,在我的例子中这不是一个问题。由于从未访问填充成员,因此移位不会导致任何SegFaults。然而,这个解决方案增加了相当多的精神开销,因为必须为每个公共功能清除对齐…


在标准C11中,您可以使用aligned_alloc()

ISO/IEC 9899:2011

7.22.3.1 The aligned_alloc function

Synopsis

1
2
#include <stdlib.h>  
void *aligned_alloc(size_t alignment, size_t size);

Description
2 The aligned_alloc function allocates space for an object whose alignment is
specified by alignment, whose size is specified by size, and whose value is
indeterminate. The value of alignment shall be a valid alignment supported by the
implementation and the value of size shall be an integral multiple of alignment.

Returns
3 The aligned_alloc function returns either a null pointer or a pointer to the allocated
space.

或者可以使用posix posix_memalign()

NAME

posix_memalign — aligned memory allocation (ADVANCED REALTIME)

SYNOPSIS

1
2
#include <stdlib.h>  
int posix_memalign(void **memptr, size_t alignment, size_t size); [Option End]

DESCRIPTION

The posix_memalign() function shall allocate size bytes aligned on a boundary specified by alignment, and shall return a pointer to the allocated memory in memptr. The value of alignment shall be a power of two multiple of sizeof(void *).

Upon successful completion, the value pointed to by memptr shall be a multiple of alignment.

If the size of the space requested is 0, the behavior is implementation-defined; the value returned in memptr shall be either a null pointer or a unique pointer.

The free() function shall deallocate memory that has previously been allocated by posix_memalign().

RETURN VALUE

Upon successful completion, posix_memalign() shall return zero; otherwise, an error number shall be returned to indicate the error.

请注意,没有aligned_realloc()或posix等效项。


您可以使用posix_memAlign进行动态对齐分配。在C11中,有一个内存对齐控件,例如本博客中的"内存对齐控件"。