C指针转换

标签 c pointers

假设我有一个字节缓冲区:

char buffer[] = {  0x11, 0x00, 0x00, 0x02, .... };

我想做的是从一个特定的偏移量中取出一个 qword。偏移量将以字节为单位计算。 这是我所做的:

unsigned long long *ptr = &buffer[16];
unsigned long long myqword = *ptr;

这似乎对我有用。我从头开始跳过 16 个字节,然后取 8 个字节。

我的问题是为什么我会收到此警告消息:

warning: initialization of ‘long long unsigned int *’ from incompatible pointer type ‘char *’ [-Wincompatible-pointer-types]
   unsigned long long *ptr = &buffer[16];

最佳答案

这里有4个主要问题:

  • unsigned long long*char* 不兼容。这是编译器错误的原因。
  • 通过 unsigned long long* 读取一堆 char 会违反 strict aliasing rule ,调用未定义的行为错误。
  • 通过 unsigned long long* 读取一堆 char 也可能导致未对齐的访问,调用未定义的行为错误。
  • 使用 char 来存储整数值是一个非常糟糕的主意,因为 char 具有实现定义的签名并且可以在某些计算机上签名。请改用 uint8_t

您应该改为使用 memcpy:

size_t n = sizeof(unsigned long long);
memcpy(&myqword, &buffer[i * n], n);

如果您确实需要访问特定内存位置的内容而不复制它,您别无选择,只能创建一些新类型,例如 union :

#include <inttypes.h>
#include <stdio.h>

typedef union
{
  uint8_t  byte [8];
  uint64_t qword;
} qword_t;

int main (void)
{
  qword_t q = {.byte = {0x11, 0x00, ...} };
  printf("%"PRIu64, q.qword);
}

但请注意,此代码取决于 CPU 字节序,不可移植。

关于C指针转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52382272/

相关文章:

c - 分配第二个数组时出现段错误

c - 字符串数组的 malloc 时出现段错误。如何摆脱它?当分配第二个维度时,我可以发现它精确地发生

c - 程序运行不佳(意味着输出(printf))但在 gdb t.exe 中运行良好

C中的纸牌游戏,随机播放链表

C++:带有 3 个星号的变量声明

创建 GUI 应用程序

c - 指向二维数组的指针

c++ - 我们应该在通过引用传递之前取消引用指针吗?

C:在c中分配的空闲内存

我们可以通过另一个包含我们希望指针指向的其他变量的地址的变量将地址分配给指针吗?