假设我分配了一些内存。
char* buffer = (char*)my_malloc(2062);
我将char值分配给先前定义的名为header的数组的前14个字节。
memcpy(buffer, header, 14);
然后我想把剩下的已分配空间当作浮动指针。
float* float_buffer = (float*)(buffer + 14);
some_function(float_buffer);
然后稍后我需要发送所有数据。
transmit(buffer);
my_free(buffer);
这是治疗记忆的正确方法吗?浮动*投射好吗?我遇到的问题是我失去了价值而没有得到正确的结果。 我的问题是: 如果你必须将分配的内存视为不同的类型,但在处理结束时将其作为char *发送.....这是正确的方法吗?
我检查了ptr值,当它们是float *和char *时它们是相同的但是我得不到正确的结果。
我的一个限制是我最初只能从静态缓冲区分配一块内存。因此不允许将另一个malloc作为不同类型(float *)调用。
答案 0 :(得分:3)
为了使这项工作(至少可移植),你必须确保(至少)float_buffer是sizeof(float)-aligned。您可以通过分配sizeof(float) - 1个额外字节,观察malloc调用modulo sizeof(float)的结果,并根据需要忽略前几个字节来完成此操作。 (当然,你必须保留原始指针才能进行free()调用。)
但你可能不想这样做。听起来“缓冲区”的目的是累积要通过网络发送的数据或类似的东西,并且浮动将从其他地方复制。你真正应该做的是反过来:始终将缓冲区视为char [],并在复制它们时将源浮点数重新解释为一系列字符。那是
char* buffer = malloc(total_size);
char* float_start = buffer + header_size;
memcpy(float_start, (char*)float_source, sizeof(float) * float_count);
transmit(buffer, total_size);
free(buffer);
答案 1 :(得分:3)
从概念上讲,这没关系 - 但你必须做一些额外的工作以确保它能够可靠地运作。
一个潜在的问题是,您不能仅以float
的形式访问任意地址。可能存在特定的对齐要求 - malloc()
返回的地址需要正确对齐以便以任何类型进行访问,但是一旦您向该地址添加14,所有投注都将关闭(除了char
)。
为确保正确对齐,您必须确保添加到buffer
的地址是sizeof(float)
的倍数。您可以使用以下公式添加填充:
#define PAD_OFFSET(offset, type) ((offset) + sizeof(type) - 1) & ~(sizeof(type) - 1))
float *float_buffer = (float *)(buffer + PAD_OFFSET(14, float));
请注意,这会在您的字符和浮点数之间创建间隙 - 填充。
或者,您可以定义struct
,编译器将为您计算填充。这使用称为灵活数组成员的C99功能:
struct foo {
char abc[14];
float xyz[];
};
struct foo *buffer = malloc(2062);
memcpy(&buffer->abc, header, 14);
some_function(&buffer->xyz);
transmit(buffer); /* Presuming transmit() expects a void * parameter. */
如果您希望在没有填充的情况下执行,则无法直接访问buffer
中的内存作为浮点数 - 您必须创建一个临时数组并将其复制到:
float temp[500]; /* Or whatever size */
some_function(&temp);
memcpy(buffer + 14, temp, sizeof temp);
答案 2 :(得分:0)
我在这里推测,但因为malloc的原型是
void *malloc(size_t size);
你实际上是将void *类型的缓冲区转换为char *,所以稍后将另一个缓冲区块转换为float *就可以了,只要你正确处理指针会计。