c - 同一动态分配中的两种类型



ISO C90标准(或者至少是我拥有的草案)对malloc和对齐进行了说明:

如果分配成功,则返回的指针适当对齐,以便它可以分配给指向任何类型的对象的指针,然后用于访问分配的空间中的此类对象或此类对象的数组...

但是,您可以将malloc返回的相同指针用于两种不同的类型吗?例如,假设我知道sizeof(int) <= 2 * sizeof(short).我可以为5shorts 分配足够的内存,并将前两个用作int,即以下代码是否保证按预期工作?

#include <stdio.h>
#include <stdlib.h>
int main(void) {
void* data = malloc(5 * sizeof(short));
short* short_array = data;
int* int_ptr = data;
if (!data) return EXIT_FAILURE;
*int_ptr = 13943;
short_array += 2; /* Skip over the int */
short_array[0] = 7;
short_array[1] = 238;
short_array[2] = -123;
printf("%d %d %d %dn", *int_ptr, short_array[0], short_array[1], short_array[2]);
free(data);
return 0;
}

我已经尝试过这段代码,它确实为我输出了13943 7 238 -123,但我不完全确定它是否符合标准。


编辑:具体来说,我正在尝试制作一个动态数组类型(可以是任何类型的数组),所以我分配了一个类型的数组,并将该分配的开头用作指向包含数组长度和容量的标头的指针。

需要明确的是,这大约是我正在做的事情:

size_t header_elements = (sizeof(ArrayHeader) + array_type_size - 1) / array_type_size); /* = ceil(sizeof(ArrayHeader) / array_type_size) */
void* data = malloc((header_elements + array_length) * array_type_size);
ArrayHeader* header = data;
void* array = (char*)data + header_elements * array_type_size;

因此,header指向分配的开始,实际array被存储在其中的类型大小的倍数偏移。

C90 现在应该已经死了,安息吧。C99、C11 和 C18 行为是这里应该考虑的行为。他们谈论了很多关于有效类型的问题。由于malloc分配的对象不是这样类型的,编译器将跟踪每个指针和内存区域的类型。

如果将int写入前 4 个字节,则允许编译器将前 4 个字节的数据类型视为int。如果随后将短字符写入连续字节,则其有效类型将为short如果存储不重叠,则您的代码正常。

但是 - 要小心:但是,如果您重叠存储,即您将short写在int上,然后读回int,那么所有赌注都关闭了。

最后,有一个相当好的方法来避免歧义 - 使用struct类型。只使用

struct two_types_in_one_malloc {
int the_int;
short the_shorts[3];
};

相关内容

  • 没有找到相关文章

最新更新