c - 同一动态分配中的两种类型
问题描述
ISO C90 标准(或至少我拥有的草案)说明了这一点malloc
并对齐:
如果分配成功,则返回的指针经过适当对齐,以便可以将其分配给指向任何类型对象的指针,然后用于访问分配的空间中的此类对象或此类对象的数组...
malloc
但是你可以为两种不同的类型使用相同的指针吗?例如,假设我知道sizeof(int) <= 2 * sizeof(short)
. 我可以为 s 分配足够的内存5
short
,并将前两个用作 s,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 %d\n", *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 个字节写入 an,则允许编译器将前 4 个字节的数据类型视为int
. 如果然后您将短裤写入连续字节,则它们的有效类型将是short
. 如果存储不重叠,那么您的代码就可以了。
但是 - 请注意:如果您与存储重叠,即您将在之后写入short
并int
回读int
,那么所有的赌注都将被取消。
最后,有一个很好的避免歧义的方法——使用struct
类型。只是使用怎么样
struct two_types_in_one_malloc {
int the_int;
short the_shorts[3];
};
推荐阅读
- python-3.x - 授权电报时如何发送确认电话
- node.js - Nodejs - 4 个进程和 VS Code 5 个进程占用内存,如任务管理器中所示
- python - 使用 jupyter 笔记本在 M1 Mac 上未定义名称“_mysql”
- symfony - 向 symfony 时间类型小时和分钟字段添加属性
- azure-machine-learning-studio - “MSIAuthentication”对象没有属性“get_token”
- django - Django + Nginx + Gunicorn 设置错误:(104:对等方重置连接)同时从上游读取响应标头
- python - Python烧瓶形式创建组消息,错误绑定参数2 - 可能不支持的类型
- javascript - 按类样式化反应渲染的 HTML
- python - discord.py bot ClientConnectorCertificateError 运行时
- paypal - 用于市场和平台的贝宝 | 订阅平台费可用吗?