C++ C指针指向C+的对齐问题+;包含对齐C结构的类

C++ C指针指向C+的对齐问题+;包含对齐C结构的类,c++,c,pointers,alignment,C++,C,Pointers,Alignment,我有以下代码: #include <iostream> #include <stdint.h> #include <stdio.h> // Structure from 3rd party that cannot be modified typedef struct { uint32_t flags; uint32_t len; uint8_t padding[120]; } mystruct_t __attribute__ ((alig

我有以下代码:

#include <iostream>
#include <stdint.h>
#include <stdio.h>

// Structure from 3rd party that cannot be modified
typedef struct  {
   uint32_t flags;
   uint32_t len;
   uint8_t padding[120];
} mystruct_t __attribute__ ((aligned(128)));

// Classes used internally
class Matcher {
};

class MatcherEQ : public Matcher {
  mystruct_t _bson;
};

Matcher* factory() {
  return new MatcherEQ();
}

// Structure used for C/C++ interface
typedef void* Match_t;

// Pure C API
extern "C" {
void CreateMatch(Match_t *pm) {
  *pm = NULL;
  Matcher *b = factory();
  *pm = (Match_t)b;
}
}

int main(void) {

  // C style code
  puts("C\n");
  Match_t m;

  CreateMatch(&m);

  // C++ code
  std::cout << "C++" << std::endl;
  Matcher *pm = factory();

  return 0;
}

运行时,我有以下输出:

C

../Sources/Tests/C/alignissue.cpp:48: runtime error: store to misaligned address 0x613000000040 for type 'struct MatcherEQ', which requires 128 byte alignment
0x613000000040: note: pointer points here
 01 00 00 62  be be be be be be be be  be be be be be be be be  be be be be be be be be  be be be be
              ^ 
../Sources/Tests/C/alignissue.cpp:41:7: runtime error: member access within misaligned address 0x613000000040 for type 'struct MatcherEQ', which requires 128 byte alignment
0x613000000040: note: pointer points here
 01 00 00 62  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00
              ^ 
../Sources/Tests/C/alignissue.cpp:41:7: runtime error: member access within misaligned address 0x613000000040 for type 'struct MatcherEQ', which requires 128 byte alignment
0x613000000040: note: pointer points here
 01 00 00 62  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  d8 c3 12 a3
              ^ 
C++

=================================================================
==21777==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 384 byte(s) in 1 object(s) allocated from:
    #0 0x7f4aa347500f in operator new(unsigned long) (../../libasan.so+0x10c00f)
    #1 0x403d05 in factory() ../Sources/Tests/C/alignissue.cpp:48
    #2 0x40402e in main ../Sources/Tests/C/alignissue.cpp:75
    #3 0x7f4aa19f5c35 in __libc_start_main (/lib64/libc.so.6+0x1ec35)

Direct leak of 384 byte(s) in 1 object(s) allocated from:
    #0 0x7f4aa347500f in operator new(unsigned long) (../../libasan.so+0x10c00f)
    #1 0x403d05 in factory() ../Sources/Tests/C/alignissue.cpp:48
    #2 0x403e31 in CreateMatch ../Sources/Tests/C/alignissue.cpp:60
    #3 0x403f17 in main ../Sources/Tests/C/alignissue.cpp:71
    #4 0x7f4aa19f5c35 in __libc_start_main (/lib64/libc.so.6+0x1ec35)

SUMMARY: AddressSanitizer: 768 byte(s) leaked in 2 allocation(s).
内存泄漏的原因是显而易见的

但我想了解并解决未对齐的地址问题

这里有
typedef void*Match\t
,因为在我的工作环境中,我只能导出纯C API。因此,我发现导出C++函数类的函数是一种解决方法。 我也没有选择gcc编译器版本:-(

GCC4.7.3(gcc的最早版本,目前在godbolt上支持执行)有():

  • alignof(MatcherEQ)=128

  • alignof(max\u align\u t)=16

(使用C++11
alignof
运算符,且未指定特定平台)

在C++2003标准中,除了“适当对齐”之外,我找不到任何关于对齐的相关措辞。在C++11中(在gcc 4.3.2发布时未完成),我们有以下措辞(我的重点):

扩展对齐由大于
alignof(std::max\u align\u t)
的对齐表示是否支持任何扩展对齐以及支持它们的上下文由实现定义(7.6.2)。具有扩展对齐要求的类型是过度对齐类型。[注意:每个过度对齐的类型都是或包含扩展对齐适用的类类型(可能通过非静态数据成员)。-结束注意]


虽然这对于您的情况来说是不确定的(因为C++11不适用于gcc 4.3.2),但可以安全地假设gcc不支持过度对齐的类型,至少在动态分配的情况下是如此(请注意,对于.

Hm,在godbolt上没有执行错误的最早gcc版本上,我得到了这样一个结论:对齐属性可能只会被堆栈上的对象接受。更新版本的gcc,带有C++17 new/delete(heap)存储,应该尊重
alignas
关键字。请回答您的问题并添加详细信息,说明您是如何编译、链接和运行您的程序的。我刚刚在Ubuntu系统上使用默认的g++8.3.0进行了尝试,无法重现该问题。我使用了
-fsanize=address
-lasan
,正如我在中所述de>-fsanitize=address
,我没有收到任何错误。但是使用
-fsanitize=undefined
时也有类似的错误。请使用更新问题details@Bodo添加了命令行。正如您所看到的,我一直坚持使用GCC4.3.2和C++98,谢谢!所以对于C++98,我唯一的解决方案似乎是实现一个支持过度对齐的堆分配器…我f可能。
C

../Sources/Tests/C/alignissue.cpp:48: runtime error: store to misaligned address 0x613000000040 for type 'struct MatcherEQ', which requires 128 byte alignment
0x613000000040: note: pointer points here
 01 00 00 62  be be be be be be be be  be be be be be be be be  be be be be be be be be  be be be be
              ^ 
../Sources/Tests/C/alignissue.cpp:41:7: runtime error: member access within misaligned address 0x613000000040 for type 'struct MatcherEQ', which requires 128 byte alignment
0x613000000040: note: pointer points here
 01 00 00 62  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00
              ^ 
../Sources/Tests/C/alignissue.cpp:41:7: runtime error: member access within misaligned address 0x613000000040 for type 'struct MatcherEQ', which requires 128 byte alignment
0x613000000040: note: pointer points here
 01 00 00 62  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  d8 c3 12 a3
              ^ 
C++

=================================================================
==21777==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 384 byte(s) in 1 object(s) allocated from:
    #0 0x7f4aa347500f in operator new(unsigned long) (../../libasan.so+0x10c00f)
    #1 0x403d05 in factory() ../Sources/Tests/C/alignissue.cpp:48
    #2 0x40402e in main ../Sources/Tests/C/alignissue.cpp:75
    #3 0x7f4aa19f5c35 in __libc_start_main (/lib64/libc.so.6+0x1ec35)

Direct leak of 384 byte(s) in 1 object(s) allocated from:
    #0 0x7f4aa347500f in operator new(unsigned long) (../../libasan.so+0x10c00f)
    #1 0x403d05 in factory() ../Sources/Tests/C/alignissue.cpp:48
    #2 0x403e31 in CreateMatch ../Sources/Tests/C/alignissue.cpp:60
    #3 0x403f17 in main ../Sources/Tests/C/alignissue.cpp:71
    #4 0x7f4aa19f5c35 in __libc_start_main (/lib64/libc.so.6+0x1ec35)

SUMMARY: AddressSanitizer: 768 byte(s) leaked in 2 allocation(s).