In case of std::counting_semaphore, I am expecting undefined behaviour in below example. Please tell me whether my understanding is correct or not

Viewed 46

In below example thread t1 is calling release() and incrementing the counter by +1 which is fine but again thread t2 is calling release() and incrementing the counter by +1 which is not satisfying the precondition and going beyond max() value ie.1 so i am thinking that i am seeing such undefined behaviour because of this thing only.please tell me is my understanding correct or not?

#include <iostream>
#include <semaphore>
#include <thread>
#include <vector>

std::vector<int> myVec{};
std::counting_semaphore<1> signal(0);              // (1)

void addElement() 
{
    std::cout << "In addElement() \n";
    myVec.insert(myVec.end(), {0, 1, 0, 3});
    std::cout << "Element added ."  << '\n';
    signal.release(); // (2)   
}

void accessElement() 
{
    std::cout << "Waiting for data accessing." << '\n';
    signal.acquire();// (3)
    std::cout << "updated the element........." << '\n';
    for (auto i: myVec) 
        std::cout << "i :" << i << " ";
    std::cout << '\n';
    std::cout << "I am at end of accessElement()" << '\n';
}

int main() 
{
    std::cout << '\n';
    std::thread t1(addElement);
    std::thread t2(addElement);
    t1.join();
    t2.join();
    std::thread t3(accessElement);
    t3.join();
    std::cout << '\n';
}

output:

Program returned: 1 
Program stderr

=1==ERROR: AddressSanitizer: new-delete-type-mismatch on 0x602000002010 in thread T0:   object passed to delete has wrong type: size of the allocated type:   16 bytes;   size of the deallocated type: -4080 bytes.
    #0 0x7f7507fc65b8 in operator delete(void*, unsigned long) (/opt/compiler-explorer/gcc-12.2.0/lib64/libasan.so.8+0xbd5b8)
    #1 0x406902 in std::__new_allocator<int>::deallocate(int*, unsigned long) /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/new_allocator.h:158
    #2 0x4058e9 in std::allocator<int>::deallocate(int*, unsigned long) /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/allocator.h:200
    #3 0x4058e9 in std::allocator_traits<std::allocator<int> >::deallocate(std::allocator<int>&, int*, unsigned long) /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/alloc_traits.h:496
    #4 0x40428f in std::_Vector_base<int, std::allocator<int> >::_M_deallocate(int*, unsigned long) /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_vector.h:387
    #5 0x403b9e in std::_Vector_base<int, std::allocator<int> >::~_Vector_base() /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_vector.h:366
    #6 0x408253 in std::vector<int, std::allocator<int> >::~vector() /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_vector.h:733
    #7 0x7f75079c58a6  (/lib/x86_64-linux-gnu/libc.so.6+0x468a6)
    #8 0x7f75079c5a5f in exit (/lib/x86_64-linux-gnu/libc.so.6+0x46a5f)
    #9 0x7f75079a3089 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24089)
    #10 0x4022ed in _start (/app/output.s+0x4022ed)

0x602000002010 is located 0 bytes inside of 16-byte region [0x602000002010,0x602000002020) allocated by thread T2 here:
    #0 0x7f7507fc56b8 in operator new(unsigned long) (/opt/compiler-explorer/gcc-12.2.0/lib64/libasan.so.8+0xbc6b8)
    #1 0x40769b in std::__new_allocator<int>::allocate(unsigned long, void const*) /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/new_allocator.h:137
    #2 0x4066e5 in std::allocator<int>::allocate(unsigned long) /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/allocator.h:188
    #3 0x4066e5 in std::allocator_traits<std::allocator<int> >::allocate(std::allocator<int>&, unsigned long) /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/alloc_traits.h:464
    #4 0x405c47 in std::_Vector_base<int, std::allocator<int> >::_M_allocate(unsigned long) /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_vector.h:378
    #5 0x405039 in void std::vector<int, std::allocator<int> >::_M_range_insert<int const*>(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int const*, int const*, std::forward_iterator_tag) /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/vector.tcc:787
    #6 0x403e1e in std::vector<int, std::allocator<int> >::insert(__gnu_cxx::__normal_iterator<int const*, std::vector<int, std::allocator<int> > >, std::initializer_list<int>) /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_vector.h:1409
    #7 0x4025c4 in addElement() /app/example.cpp:12
    #8 0x408356 in void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void (*&&)()) /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/invoke.h:61
    #9 0x4082ee in std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void (*&&)()) /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/invoke.h:96
    #10 0x40829b in void std::thread::_Invoker<std::tuple<void (*)()> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/std_thread.h:252
    #11 0x40826f in std::thread::_Invoker<std::tuple<void (*)()> >::operator()() /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/std_thread.h:259
    #12 0x4081c5 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()>
> >::_M_run() /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/std_thread.h:210
    #13 0x7f7507dc1a32  (/opt/compiler-explorer/gcc-12.2.0/lib64/libstdc++.so.6+0xe0a32)

Thread T2 created by T0 here:
    #0 0x7f7507f56136 in pthread_create (/opt/compiler-explorer/gcc-12.2.0/lib64/libasan.so.8+0x4d136)
    #1 0x7f7507dc1d3b in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (/opt/compiler-explorer/gcc-12.2.0/lib64/libstdc++.so.6+0xe0d3b)
    #2 0x4029af in main /app/example.cpp:32
    #3 0x7f75079a3082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)

SUMMARY: AddressSanitizer: new-delete-type-mismatch (/opt/compiler-explorer/gcc-12.2.0/lib64/libasan.so.8+0xbd5b8) in operator delete(void*, unsigned long)
==1==HINT: if you don't care about these errors you may set ASAN_OPTIONS=new_delete_type_mismatch=0
==1==ABORTING x86-64 gcc 12.2 - cached
0 Answers
Related