Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何修复未对齐的指针(字符**)_C++_Macos_Pointers_Alignment - Fatal编程技术网

C++ 如何修复未对齐的指针(字符**)

C++ 如何修复未对齐的指针(字符**),c++,macos,pointers,alignment,C++,Macos,Pointers,Alignment,Clang 3.3 UBSan(未定义的行为消毒剂)为未对齐的访问标记了以下代码: Address.cc:545:27: runtime error: load of misaligned address 0x60c00000a7df for type 'char *', which requires 8 byte alignment 0x60c00000a7df: note: pointer points here 00 00 00 00 ef a7 00 00 c0 60 00 00 0

Clang 3.3 UBSan(未定义的行为消毒剂)为未对齐的访问标记了以下代码:

Address.cc:545:27: runtime error: load of misaligned address 0x60c00000a7df for type 'char *', which requires 8 byte alignment
0x60c00000a7df: note: pointer points here
 00 00 00 00 ef  a7 00 00 c0 60 00 00 00  00 00 00 00 00 00 00 c0  a8 64 0c 00 00 00 00 00  00 00 00
             ^
Address.cc:547:19: runtime error: reference binding to misaligned address 0x60c00000a7ef for type 'const struct in_addr', which requires 4 byte alignment
0x60c00000a7ef: note: pointer points here
 00 00 00 00 c0  a8 64 0c 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00
             ^
问题代码如下所示(忽略
运算符=
的错误返回类型):

以及
hostent
结构:

struct hostent {
  char    *h_name;        /* official name of host */
  char    **h_aliases;    /* alias list */
  int     h_addrtype;     /* host address type */
  int     h_length;       /* length of address */
  char    **h_addr_list;  /* list of addresses */
}
这个嘎嘎声是在MacOSX系统上产生的,我记得最近有一次讨论说这是Xcode或CFEDev邮件列表上的一个bug(但我现在找不到它)

编辑:肖恩·麦克布莱德(Sean McBride)很友好地提供了电子邮件链接:我不同意可以忽略它的说法(因为它来自操作系统而不是应用程序),特别是因为它可能导致
SIGBUS
错误


如何重新调整指针以清除叮当声问题(
h\u addr
给我带来的麻烦最大)?由于苹果公司的内部结构依赖于它,这甚至可以实现吗?

如果您有一个指向数据的指针,该指针包含正确的值,但偏移量不正确,您可能需要
memcpy
该数据。在您的例子中,将
ipv4
转换为堆栈变量(将对齐),并
memcpy
s.h\u addr\u列表[0]
转换为
ipv4

以下是我最后在Mac OS X 10.8.3上修复两个未对齐指针的操作。(为了完整起见,Ubuntu 13(x64)上没有出现这些问题


JWW的修复对于C++来说非常有用,但是,对于C来说,需要进行一些修改:将“InAdDr”改为“Stimt InAdDr”。 我必须移植类似的代码,以便与之前(未对齐的内存访问)进行比较:

之后,使用memcpy进行正确的内存对齐:

char **ip_addr;
memcpy(&ip_addr, &(host->h_addr_list[0]), sizeof(void *));
memcpy(&address.sin_addr.s_addr, ip_addr, sizeof(struct in_addr));

C++中没有必要指定一个元素是一个结构:<代码> const Stutt Stuts& S/<代码>应该是代码> const and s>代码,也就是管理员的正确行为是返回一个引用对象,谢谢MAN33637。上面的代码是存在的。我关心的是未对齐访问的运行时错误,而不是语言问题。如果SIGBUS没有实际触发SIGBUS,您不必担心SIGBUS,事实上,在x64和类似的CPU上,它不会触发任何SIGBUS。也就是说,您确实可以忽略UBSan运行时警告。如果您将端口连接到一个可能导致SIGBU的平台S、 然后,该平台上的相关
libc
函数可能不会生成具有此类对齐问题的
struct hostent
对象,否则任何访问它们的操作都会崩溃。感谢MSalters。本质上,
S.h_addr
是一个
char**
。但我无法在没有总线错误的情况下解除对它的引用。我确实尝试了e> memcpy将其删除,但我仍然收到一个未对齐访问的错误。因此,
memcpy
删除一个未对齐的访问,但不能同时删除两个。在
操作符=
调用期间,剩下的一个似乎在差异中。(而且,
operator=
返回的不是我现在愿意打的一场战斗,因为它不会产生运行时错误;)对齐错误不是来自
memcpy
。不是这样的。
void DoSomethingWithHostent(const hostent& he)
{
  // Mac OS X work around 1. Align hostent's h_addr.
  char** ip_addr;
  const void* ptr = (void*)&s.h_addr;
  memcpy(&ip_addr, ptr, sizeof(void*));

  // Mac OS X work around 2. Align in_addr's via memcpy below.
  typedef struct {
    union {
        in_addr ipv4;
        in6_addr ipv6;
    };
  } IN_ADDR_4or6;

  IN_ADDR_4or6 ipv4or6;

  // Back to business logic
  switch (s.h_addrtype) {

  case AF_INET:
    memcpy(&ipv4or6.ipv4, ip_addr, sizeof(ipv4or6.ipv4));
    DoSomethingWithInAddr(ipv4or6.ipv4);
    break;
  ...
  }
}
address.sin_addr.s_addr = ((struct in_addr *)(host->h_addr_list[0]))->s_addr;
char **ip_addr;
memcpy(&ip_addr, &(host->h_addr_list[0]), sizeof(void *));
memcpy(&address.sin_addr.s_addr, ip_addr, sizeof(struct in_addr));