将分配的内存视为不同的类型

时间:2010-11-30 05:58:21

标签: c memory pointers

假设我分配了一些内存。

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 *)调用。

3 个答案:

答案 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 *就可以了,只要你正确处理指针会计。