memory
                                
                                 memory copied to clipboard
                                
                                    memory copied to clipboard
                            
                            
                            
                        ARM64 crash when using static block allocator with small types
Crash when deallocating shared_ptr building for arm64 -- Xcode Apple clang version 14.0.3 (clang-1403.0.22.14.1)
Has been happening for a couple major Xcode versions so far.
Example program
using StaticMemoryPoolAllocator =
    foonathan::memory::memory_pool<foonathan::memory::node_pool, foonathan::memory::static_block_allocator>
size_t Capacity = 20;
using TestType = int;
using NodeSize = shared_ptr_stateful_node_size<TestType>;
constexpr size_t storage_size_bytes = StaticMemoryPoolAllocator::min_block_size( NodeSize::value, Capacity );
// setup storage & pool
foonathan::memory::static_allocator_storage<storage_size_bytes> storage;
StaticMemoryPoolAllocator pool( NodeSize::value, storage_size_bytes, storage );
// test case
std::list<std::shared_ptr<TestType>> retain;
for ( size_t i = 0; i < capacity; ++i ) {
    retain.push_back( foonathan::memory::allocate_shared<TestType>( pool ) );
}
retain.clear(); // < crash here
In fact, resetting the shared_ptr of the 2nd created item can cause a crash.
In my experimenting, the only thing that alleviated the crash was to use TestType with a sizeof 8 or higher.
I don't have access to XCode, can you please give me the following information:
- shared_ptr_stateful_node_size<TestType>::value
- How many bytes are allocated by memory::allocate_shared<TestType>(pool)(you can find it out by setting a breakpoint instd_allocator::allocate, the value isn * sizeof(T)of whatever allocator instantiation was being used.
- If  there is a mismatch between 1 and 2, the output of nodesize_dbg --verbose
Thank you.
Sorry for the long delay, here is the info
using TestType = int;
- sizeof(int)= 4,- alignof(int)= 4
- shared_ptr_stateful_node_size<int>::value= 44
- memory::allocate_shared<TestType>(pool)->- std_allocator::allocate= n = 1- std::allocator::allocate_impl:
 taking the- void* allocate_impl(std::false_type, size_type n) { if (n == 1) return this->allocate_node(sizeof(T), alignof(T)); else return this->allocate_array(n, sizeof(T), alignof(T)); }- n == 1branch here,- sizeof(T)= 40,- alignof(T)= 8.
- so I think therefore it is allocating 48, but the determined size is 44 from (1) above
 
- see attached nodesize_dbg_verbose.txt
It seems the discrepancy in (1) is that detail::shared_ptr_stateful_node_size<alignof(T)>::value + sizeof(T) here we take the alignof(int)
BUT in (2) the allocator impl is taking the alignof(shared_ptr_stateful_node_size<int>)
The type of the std_allocator is
foonathan::memory::std_allocator<
    std::__shared_ptr_emplace<
        int,
        foonathan::memory::std_allocator<
            int,
            rt::StaticMemoryPool<
                20,
                shared_ptr_stateful_node_size<int>,
                rt::container_overhead::None
            >
        >
    >,
    rt::StaticMemoryPool<
        20,
        shared_ptr_stateful_node_size<int>,
        rt::container_overhead::None
    >
> 
The rt::StaticMemoryPool is my implementation of an allocator-- the 1st argument is the capacity, the 2nd template argument is used to determine the size of the nodes