2010-11-30 47 views
0

假设我分配了一些内存。将分配的内存视为不同的类型

char* buffer = (char*)my_malloc(2062); 

我将char值赋给前面定义的数组命名头的前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

这听起来像你有一个对齐问题;你能展示预期的结果和你看到的实际错误吗? – 2010-11-30 06:09:34

+0

是的,这是一个对齐问题......我不知道的东西。我可以从这里拿走它。谢谢。 – 2010-11-30 06:46:49

回答

3

为了使这项工作(至少可移植),你必须确保(至少)float_buffer是sizeof(float)对齐的。你可以通过分配sizeof(float) - 1个额外的字节,观察malloc调用的模数sizeof(float)的结果,并忽略前几个字节来做到这一点。 (当然,为了进行免费()调用,您必须保留原始指针。)

虽然您可能不想这样做。这听起来像'缓冲区'的目的是积累数据通过网络发送或类似的东西,而浮动将被从其他地方复制。你真正应该做的是另一种方式:将缓冲区作为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); 
+0

+1避免校准头痛的好方法。 – 2010-11-30 06:10:54

0

我在这里猜测,但由于原型的malloc是

void *malloc(size_t size); 

你基本上是铸造void *类型的缓冲区为char *,所以后来铸造缓冲的另一块浮动*将会很好,只要你照顾好指针会计。

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); 
相关问题