在C中重新解释内存的正确方法是什么?

时间:2013-06-27 16:47:31

标签: c pointers memory undefined-behavior

很久以前,我在C中做过类似事情的次数已经失去了数:

struct foo f;
struct foo* pf = &f;
char* pc = (char*) pf;
transmit(pc, sizeof(f));

或者也许:

char* buffer[1024];
receive(buffer, 1024);
float values[256];
for(int ii = 0; ii < 256; ii++) {
    float* pf = (float*)(buffer + ii*4);
    values[ii] = *pf;
}

或者也许:

uint32_t ipAddress = ...;
uint8_t* p = (uint8_t*)&ipAddress;
uint8_t octets[4] = {p[0], p[1], p[2], p[3]};
printf("%d.%d.%d.%d\n", octets[0], octets[1], octets[2], octets[3]);

我刚刚发现通过强制转换为另一种指针类型来重新解释这样的内存会调用未定义的行为。然而,所有上述例子都是绝对必要的。这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:5)

转换为char *(或unsigned char *或其typedef)是一种特殊情况,并且导致未定义的行为。

根据C规范, 6.3.2.3指针,第7段:

  

当指向对象的指针转换为指向字符类型的指针时,结果指向对象的最低寻址字节。结果的连续增量,直到对象的大小,产生指向对象剩余字节的指针。

你的第一个&amp;本案涵盖了第三个例子。第二个例子有点狡猾,但可能适用于大多数系统。你真正应该做的事情是直接阅读values

float values[256];
receive(values, sizeof values); // assuming receive() takes a "void *" parameter

或类似的东西(以避免对齐问题):

char buffer[1024];
receive(buffer, sizeof buffer);
float values[256];
for(int i = 0; i < 256; i++)
{
    char *pf = (char *)&values[i];
    memcpy(pf, buffer + i * sizeof(float), sizeof(float));
}

(注意我将buffer更改为char数组 - 我认为这是你问题中的拼写错误。)

相关问题