最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - ASan new_delete_type_mismatch due to over alignment - Stack Overflow

programmeradmin1浏览0评论

Consider the following code snippet:

#include <new>
int main() {
    delete new (std::align_val_t(16)) char;
}

g++ 14.2.1 compiles it without warning (under -Wall -pedantic) and it runs without error. But when compiled with -fsanitize=address, ASan reports the following:

==17707==ERROR: AddressSanitizer: new-delete-type-mismatch on 0x503000000040 in thread T0:
  object passed to delete has wrong type:
  size of the allocated type:   1 bytes;
  size of the deallocated type: 1 bytes.
  alignment of the allocated type:   16 bytes;
  alignment of the deallocated type: default-aligned.
    #0 0x70912beff4f2 in operator delete(void*, unsigned long) /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_new_delete.cpp:164
    #1 0x6493bc2dd18d in main (/tmp/a.out+0x118d) (BuildId: e8f06d0aee8e301d7f1522801237096f3006c790)
    #2 0x70912b835487  (/usr/lib/libc.so.6+0x27487) (BuildId: 695cfc6aac7d0f77bb7caba0ef01b2e868762b02)
    #3 0x70912b83554b in __libc_start_main (/usr/lib/libc.so.6+0x2754b) (BuildId: 695cfc6aac7d0f77bb7caba0ef01b2e868762b02)
    #4 0x6493bc2dd094 in _start (/tmp/a.out+0x1094) (BuildId: e8f06d0aee8e301d7f1522801237096f3006c790)

0x503000000040 is located 0 bytes inside of 1-byte region [0x503000000040,0x503000000041)
allocated by thread T0 here:
    #0 0x70912befe97a in operator new(unsigned long, std::align_val_t) /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_new_delete.cpp:107
    #1 0x6493bc2dd17b in main (/tmp/a.out+0x117b) (BuildId: e8f06d0aee8e301d7f1522801237096f3006c790)
    #2 0x70912b835487  (/usr/lib/libc.so.6+0x27487) (BuildId: 695cfc6aac7d0f77bb7caba0ef01b2e868762b02)
    #3 0x70912b83554b in __libc_start_main (/usr/lib/libc.so.6+0x2754b) (BuildId: 695cfc6aac7d0f77bb7caba0ef01b2e868762b02)
    #4 0x6493bc2dd094 in _start (/tmp/a.out+0x1094) (BuildId: e8f06d0aee8e301d7f1522801237096f3006c790)

SUMMARY: AddressSanitizer: new-delete-type-mismatch /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_new_delete.cpp:164 in operator delete(void*, unsigned long)

Is this a false positive by ASan? Or is it actually required to pair "aligned new" calls with "aligned delete" calls? Is it undefined behavior if not paired?

Edit: I suppose [new.delete] is relevant. But then my question becomes what is the best practice for freeing over-aligned memory (say, 32-byte aligned array of doubles for SIMD purposes)? Is it best to call operator delete explicitly?

Consider the following code snippet:

#include <new>
int main() {
    delete new (std::align_val_t(16)) char;
}

g++ 14.2.1 compiles it without warning (under -Wall -pedantic) and it runs without error. But when compiled with -fsanitize=address, ASan reports the following:

==17707==ERROR: AddressSanitizer: new-delete-type-mismatch on 0x503000000040 in thread T0:
  object passed to delete has wrong type:
  size of the allocated type:   1 bytes;
  size of the deallocated type: 1 bytes.
  alignment of the allocated type:   16 bytes;
  alignment of the deallocated type: default-aligned.
    #0 0x70912beff4f2 in operator delete(void*, unsigned long) /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_new_delete.cpp:164
    #1 0x6493bc2dd18d in main (/tmp/a.out+0x118d) (BuildId: e8f06d0aee8e301d7f1522801237096f3006c790)
    #2 0x70912b835487  (/usr/lib/libc.so.6+0x27487) (BuildId: 695cfc6aac7d0f77bb7caba0ef01b2e868762b02)
    #3 0x70912b83554b in __libc_start_main (/usr/lib/libc.so.6+0x2754b) (BuildId: 695cfc6aac7d0f77bb7caba0ef01b2e868762b02)
    #4 0x6493bc2dd094 in _start (/tmp/a.out+0x1094) (BuildId: e8f06d0aee8e301d7f1522801237096f3006c790)

0x503000000040 is located 0 bytes inside of 1-byte region [0x503000000040,0x503000000041)
allocated by thread T0 here:
    #0 0x70912befe97a in operator new(unsigned long, std::align_val_t) /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_new_delete.cpp:107
    #1 0x6493bc2dd17b in main (/tmp/a.out+0x117b) (BuildId: e8f06d0aee8e301d7f1522801237096f3006c790)
    #2 0x70912b835487  (/usr/lib/libc.so.6+0x27487) (BuildId: 695cfc6aac7d0f77bb7caba0ef01b2e868762b02)
    #3 0x70912b83554b in __libc_start_main (/usr/lib/libc.so.6+0x2754b) (BuildId: 695cfc6aac7d0f77bb7caba0ef01b2e868762b02)
    #4 0x6493bc2dd094 in _start (/tmp/a.out+0x1094) (BuildId: e8f06d0aee8e301d7f1522801237096f3006c790)

SUMMARY: AddressSanitizer: new-delete-type-mismatch /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_new_delete.cpp:164 in operator delete(void*, unsigned long)

Is this a false positive by ASan? Or is it actually required to pair "aligned new" calls with "aligned delete" calls? Is it undefined behavior if not paired?

Edit: I suppose [new.delete] is relevant. But then my question becomes what is the best practice for freeing over-aligned memory (say, 32-byte aligned array of doubles for SIMD purposes)? Is it best to call operator delete explicitly?

Share Improve this question edited Feb 6 at 16:16 YiFei asked Feb 6 at 8:49 YiFeiYiFei 1,8341 gold badge20 silver badges36 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

ASAN is right and reports the issue correctly. std::align_val_t:

Both new-expression and delete-expression, when used with objects whose alignment requirement is greater than __STDCPP_DEFAULT_NEW_ALIGNMENT__, pass that alignment requirement as an argument of type std::align_val_t to the selected allocation/deallocation function.

The correct usage:

::operator delete (new (std::align_val_t(16)) char, std::align_val_t(16));

https://godbolt.org/z/zrK1ffdEx

发布评论

评论列表(0)

  1. 暂无评论