Can a char array be used with any data type?

前端 未结 3 1088
遇见更好的自我
遇见更好的自我 2020-12-31 18:32

The malloc() function returns a pointer of type void*. It allocates memory in bytes according to the size_t value passed as argument t

3条回答
  •  渐次进展
    2020-12-31 18:50

    No you cannot use an arbitrary byte array for an arbitrary type because of possible alignment problems. The standard says in 6.3.2.3 Conversions/Pointers (emphasize mine):

    A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer.

    As a char as the smallest alignment requirement, you cannot make sure that your char array will be correctly aligned for any other type. That is why malloc guarantees that a buffer obtained by malloc (even if it is a void *) has the largest possible alignement requirement to be able to accept any other type.


    I think that

    union {
        char buf[128];
        long long i;
        void * p;
        long double f;
    };
    

    should have correct alignment for any type as it is compatible with largest basic types (as defined in 6.2.5 Types). I am pretty sure that it will work for all common implementations (gcc, clang, msvc, ...) but unfortunately I could not find any confirmation that the standard allows it. Essentially because of the strict aliasing rule as defined in 6.5 Expression §7:

    An object shall have its stored value accessed only by an lvalue expression that has one of the following types:

    • a type compatible with the effective type of the object,
    • a qualified version of a type compatible with the effective type of the object,
    • a type that is the signed or unsigned type corresponding to the effective type of the object,
    • a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
    • an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or
    • a character type.

    So IMHO there is not portable and standard conformant way to build a custom allocator not using malloc.

提交回复
热议问题