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