将双指针转换为 char 指针有什么问题吗?以下代码中的目标是以三种不同的方式更改 1 元素。
double vec1[100];
double *vp = vec1;
char *yp = (char*) vp;
vp++;
vec1[1] = 19.0;
*vp = 12.0;
*((double*) (yp + (1*sizeof (vec1[0])))) = 34.0;
对于较新的 INTEL 处理器,您可能遇到的主要问题是对齐。假设你要写这样的东西:
*((double*) (yp + 4)) = 34.0;
然后你可能会遇到运行时错误,因为双精度应该在 8 个字节上对齐。在 68k 或 MIPS 等处理器上也是如此。
这类似于拥有一个结构并在该结构上进行强制转换。您不太可能破坏事物。
在大多数情况下,如果你能避免这种情况,你的代码会更强大。就个人而言,我什至在读取文件时都不会使用这种强制转换。相反,我从文件中获取数据并根据需要将其放入结构中。假设我在缓冲区中读取 4 个字节以转换为整数,我会这样写:
unsigned char buf[4];
...
fread(buf, 1, 4, f);
my_struct.integer = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
现在我没有做丑陋的演员表,我可以控制文件中整数的字节序,无论你运行的处理器的字节序是什么。
这种类型的演员属于“如果你知道自己在做什么就可以,但如果你不知道就危险”的类别。
例如,在这种情况下,您已经知道 "yp" 的指针值(它指向 a double
),因此将其值增加 a 的大小double
并重新转换回 a在技术上是安全的double*
。
一个反例:假设您不知道char*
来自哪里……比如说,它是作为函数参数提供给您的。现在,你的演员将是一个大问题:因为从char*
技术上讲是 1 字节对齐的,而 adouble
通常是 8 字节对齐的,你不能确定你是否得到了一个 8 字节对齐的地址。如果它是对齐的,你的算术将产生一个有效的double*
; 如果没有,它会在取消引用时崩溃。
这只是演员阵容如何出错的一个例子。你正在做的事情(乍一看)看起来会奏效,但总的来说,当你施放东西时,你真的必须注意。