thread_local static class is destroyed at invalid address on program exit - c++

I have an issue with the destruction of a thread_local static object.
#include <iostream>
#include <thread>
struct UsesLoc {
UsesLoc() {
loc.counter++;
}
struct Loc {
Loc() {
std::cout << "I am at " << this << " and counter is " << counter << std::endl;
}
~Loc() {
std::cout << "I was at " << this << " and counter is " << counter << std::endl;
}
int counter = 0;
};
static thread_local Loc loc;
};
thread_local UsesLoc::Loc UsesLoc::loc;
int main()
{
{
UsesLoc usesloc;
std::cout << "loc is at " << &UsesLoc::loc << " and counter is " << UsesLoc::loc.counter << std::endl;
}
return 0;
}
As expected, compiling and running on https://coliru.stacked-crooked.com/a/e8bcfdaffa6a6da7 reveals that the thread_local object is always at the same location and the counter values are (0,1,1):
I am at 0x7f9dc817673c and counter is 0
loc is at 0x7f9dc817673c and counter is 1
I was at 0x7f9dc817673c and counter is 1
Conversely, when I locally compile with MinGW and run, I get, for instance,
I am at 0x507874 and counter is 0
loc is at 0x507874 and counter is 1
I was at 0x7efdd000 and counter is 2686552
Clearly, an uninitialized object at a different memory location is destroyed.
Did I oversee anything non-deterministic? How can I ensure that the correct object is destroyed?

After getting a hint from Ted Lyngmo that this might be a compiler bug, I did a bit of research and it seems to be indeed an issue already reported before:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562
https://sourceforge.net/p/mingw-w64/bugs/527/
https://sourceforge.net/p/mingw-w64/bugs/727/
That being said, the code is correct and the pointer to the object being destructed points to the same object that was constructed before when using a standard-compliant compiler.

Related

Memory fault when print *pointer

Why do I have a memory fault in the below code? How do I fix it?
I want to read the progress of the outside function.
But I only get the output get_report_progress:100
#include <iostream>
int* int_get_progress = 0;
void get_progress(int* int_get_progress)
{
int n = 100;
int *report_progress = &n;
int_get_progress = report_progress;
std::cout << "get_report_progress:" << *int_get_progress <<std::endl;
}
int main()
{
get_progress(int_get_progress);
std::cout << "main get process:" << *int_get_progress << std::endl;
return 0;
}
Your global int_get_progress variable is a pointer that is initialized to null. You are passing it by value to the function, so a copy of it is made. As such, any new value the function assigns to that pointer is to the copy, not to the original. Thus, the global int_get_progress variable is left unchanged, and main() ends up deferencing a null pointer, which is undefined behavior and in this case is causing a memory fault.
Even if you fix the code to let the function update the caller's pointer, your code would still fail to work properly, because you are setting the pointer to point at a local variable that goes out of scope when the function exits, thus you would leave the pointer dangling, pointing at invalid memory, which is also undefined behavior when that pointer is then dereferenced.
Your global variable (which doesn't need to be global) should not be a pointer at all, but it can be passed around by pointer, eg:
#include <iostream>
void get_progress(int* p_progress)
{
int n = 100;
*p_progress = n;
std::cout << "get_report_progress:" << *p_progress << std::endl;
}
int main()
{
int progress = 0;
get_progress(&progress);
std::cout << "main get process:" << progress << std::endl;
return 0;
}
Alternatively, pass it by reference instead, eg:
#include <iostream>
void get_progress(int& ref_progress)
{
int n = 100;
ref_progress = n;
std::cout << "get_report_progress:" << ref_progress << std::endl;
}
int main()
{
int progress = 0;
get_progress(progress);
std::cout << "main get process:" << progress << std::endl;
return 0;
}
Alternatively, don't pass it around by parameter at all, but return it instead, eg:
#include <iostream>
int get_progress()
{
int n = 100;
std::cout << "get_report_progress:" << n << std::endl;
return n;
}
int main()
{
int progress = get_progress();
std::cout << "main get process:" << progress << std::endl;
return 0;
}

C++ shared_from_this() is not letting obj get destructed

I have a following piece of code, which is creating a simple object of Name and inside that it is creating another object Name, with a shared_from_this() reference. As I am reading from here
https://en.cppreference.com/w/cpp/memory/enable_shared_from_this/shared_from_this
"Effectively executes std::shared_ptr(weak_this), where weak_this is the private mutable std::weak_ptr member of enable_shared_from_this."
Which I am understanding as shared_from_this() is only creating a weak pointer to shared obj. But I don't see this is the case in runtime. There is effectively a circular reference getting created.
At the end of the I was expecting the Name obj should be destructed, but it is not because the reference counter is 2.
Can someone help me understand how should I use enable_shared_from_this(), that can effectively cleanup the Name obj, once it goes out of reference.
#include <iostream>
#include <memory>
#include <string>
#include <chrono>
#include <thread>
using namespace std;
struct Another;
struct Name : public std::enable_shared_from_this<Name> {
std::string t;
int m, n, p;
shared_ptr<Another> ann;
Name() {
std::cout << "constructor\n";
}
void MakeSomething() {
ann = std::make_shared<Another>(shared_from_this());
}
~Name() {
std::cout << "destructor\n";
}
};
struct Another {
shared_ptr<Name> nn;
Another(shared_ptr<Name> n) : nn(n) {
std::cout << "from another constructor " << nn.use_count() << "\n";
}
~Another() {
std::cout << "from another destructor\n";
}
};
int main()
{
{
auto n = std::make_shared<Name>();
std::cout << "Name ref count so far: " << n.use_count() << "\n";
auto p = n.get();
//delete p;
std::cout << "Name ref count so far: " << n.use_count() << "\n";
n->MakeSomething();
std::cout << "Name ref count so far: " << n.use_count() << "\n";
{
shared_ptr<Name> m = n;
std::cout << "Name ref count so far: " << n.use_count() << "\n";
}
std::cout << "Name ref count so far: " << n.use_count() << "\n";
}
// problem: at this point Name obj, should go out of reference and destructor to be called, which is NOT happening
return 0;
}
And here is the runtime output (compiler used msvc)
constructor
Name ref count so far: 1
Name ref count so far: 1
from another constructor 3
Name ref count so far: 2
Name ref count so far: 3
Name ref count so far: 2
Which I am understanding as shared_from_this() is only creating a weak pointer to shared obj. But I don't see this is the case in runtime. There is effectively a circular reference getting created.
shared_from_this() is creating a weak_ptr, which you're passing to a shared_ptr constructor, as specified by (11) here. That constructor creates a shared_ptr to the same object, increasing the reference count.
Also keep in mind that weak_ptr does not contribute to the reference count at all, so it has no bearing on your confusion over the reference count. Focus on what the shared_ptrs are doing.

Cpp thread object and shared_ptr issue

When I read the document in cppreference here
https://en.cppreference.com/w/cpp/memory/shared_ptr#Example
I am wondering what the possible value of the first lp.use_count() printed out is? I marked it with "<<<<<" in output content.
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>
struct Base
{
Base() { std::cout << " Base::Base()\n"; }
// Note: non-virtual destructor is OK here
~Base() { std::cout << " Base::~Base()\n"; }
};
struct Derived: public Base
{
Derived() { std::cout << " Derived::Derived()\n"; }
~Derived() { std::cout << " Derived::~Derived()\n"; }
};
void thr(std::shared_ptr<Base> p)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::shared_ptr<Base> lp = p; // thread-safe, even though the
// shared use_count is incremented
{
static std::mutex io_mutex;
std::lock_guard<std::mutex> lk(io_mutex);
std::cout << "local pointer in a thread:\n"
<< " lp.get() = " << lp.get()
<< ", lp.use_count() = " << lp.use_count() << '\n';
}
}
int main()
{
std::shared_ptr<Base> p = std::make_shared<Derived>();
std::cout << "Created a shared Derived (as a pointer to Base)\n"
<< " p.get() = " << p.get()
<< ", p.use_count() = " << p.use_count() << '\n';
std::thread t1(thr, p), t2(thr, p), t3(thr, p);
p.reset(); // release ownership from main
std::cout << "Shared ownership between 3 threads and released\n"
<< "ownership from main:\n"
<< " p.get() = " << p.get()
<< ", p.use_count() = " << p.use_count() << '\n';
t1.join(); t2.join(); t3.join();
std::cout << "All threads completed, the last one deleted Derived\n";
}
Possible output:
Base::Base()
Derived::Derived()
Created a shared Derived (as a pointer to Base)
p.get() = 0x2299b30, p.use_count() = 1
Shared ownership between 3 threads and released
ownership from main:
p.get() = 0, p.use_count() = 0
local pointer in a thread:
lp.get() = 0x2299b30, lp.use_count() = 5 <<<<<<<< HERE <<<<<<
local pointer in a thread:
lp.get() = 0x2299b30, lp.use_count() = 3
local pointer in a thread:
lp.get() = 0x2299b30, lp.use_count() = 2
Derived::~Derived()
Base::~Base()
All threads completed, the last one deleted Derived
#user2452809 's answer is very appreciated, which pointed out an important feature of use_count().
Supposing use_count() would return an accurate count, what would be the answer?
I wouldn't rely on that value anyway.
In multithreaded environment, the value returned by use_count is approximate (typical implementations use a memory_order_relaxed load)
Check the reference for more information: https://en.cppreference.com/w/cpp/memory/shared_ptr/use_count
I think it could be one value of {4,5,6}. Am I right?
Q: Why larger than 3?
A: When printing, at least one thr function is invoked. Including the reference in main function. the use_count should be 3. But it's not possible when one thread sleep for one second and other two hadnot been constructed.
On the other hand, if there're two threads finished, the last thread would have a use_count 3. But it would not be the first line because of the thread mutex in printing scope.
Q: Why less than 7?
A: Because during the sleep in subthread, the main thread will run p.reset(). One second is a quite long time to CPU.

How does counter decrement of smart pointer work?

Below is a sample code for shared pointer. I define a shared pointer inside curly braces scope. sp1 is initialized by new A (counter = 1) and sp1 is assigned to sp2 (copy and/or assignment increase the counter by 1 so, counter = 2). I always thought destructor of the A is called when counter becomes 0. But in my case the smart pointer when is about to get out of scope ( via the curly brace ) the counter is two.
My question is : who changed the counter from 2 to 0?
#include <iostream>
#include <memory>
using namespace std;
class A{
public:
~A(){
std::cout << "~A" << std::endl;
}
};
int main(){
{
shared_ptr<A> sp1 (new A);
shared_ptr<A> sp2 = sp1;
std::cout << "sp1 count = " << sp1.use_count() << std::endl;
std::cout << "sp2 count = " << sp2.use_count() << std::endl;
}
return 0;
}
EDIT:
Link to paper on smart pointer
output:
sp1 count = 2
sp2 count = 2
~A
When your code gets to the end of main, the destructor for both sp1 and sp2 runs, which decrements the counter to zero - that is a VERY important part of shared pointers, that the destructor reduces the reference count and thus, when "nothing" is left, the destructor of the actual shared object gets called.
The destuctor of shared_ptr will have some logic like this:
counter--; // Should be atomic!
if (counter == 0)
{
delete owned_thing;
}
A better example (IMO) would be something like this:
int main()
{
std::shared_ptr<A> sp1{new A};
std::cout << "1: sp1.use_count() = " << sp1.use_count() << '\n';
{
std::shared_ptr<A> sp2 = sp1;
std::cout << "2: sp1.use_count() = " << sp1.use_count() << '\n';
std::cout << "2: sp2.use_count() = " << sp2.use_count() << '\n';
}
std::cout << "3: sp1.use_count() = " << sp1.use_count() << '\n';
}
The output from this program should be (using your class with its destructor):
1: sp1.use_count() = 1
2: sp1.use_count() = 2
2: sp2.use_count() = 2
3: sp1.use_count() = 1
~A
First you create a shared pointer and initialize it, making the use counter 1. Then you enter a new scope and in it create a new shared pointer initializing it (using the shared pointers copy-constructor) with the old pointer, leading to the use count of both pointers being 2. Then the second shared pointer goes out of scope, and the shared pointer destructor decrements the use count by one. Finally the second shared pointer goes out of scope, as the main function returns, and the use count is decremented by the sp1 destructor. Now it has reached zero, and the contained pointer is deleted resulting in the A destructor being called.

using int pointer in multiple couts

I'm quite new to the world of pointers in C/C++ so this may be quite an easy question for you:
The following C++-Code works normally
#include <iostream>
int main()
{
int theInt = 1337;
int & theReference = theInt;
int * thePointer = &theInt;
std::cout << "int: " << theInt << "\n";
std::cout << "referenz: " << theReference << "\n";
std::cout << "pointer: " << *thePointer << "\n";
std::cout << "pointer: " << *thePointer << "\n";
//std::cout << "foo" << "\n";
return 0;
}
but stops working when changing
//std::cout << "foo" << "\n";
to
std::cout << "foo" << "\n";
.
By "stops working" I mean: "is blocked by my norton security as a potential threat" (resulting in a return code of "0x76F531AF" if this is any help). Since norton normally doesn't interfere withe my programming I assume the double use of the int pointer in cout somehow results in a segfault...
Thx for your help!
PS:
I use Code::Blocks on Windows 8.1 with the GCC compiler and GDB debugger from TDM-GCC (version 4.7.1, 32 bit).
EDIT: removed deletion of pointer -> problem remains.
You can only delete objects created on the heap (using new or C-style malloc and such).
// allocate on the heap
int *intOnTheHeap = new int;
// do some stuff with it
*intOnTheHeap = 0;
(*intOnTheHeap)++;
std::cout << *intOnTheHeap << std::endl;
// deallocate
delete intOnTheHeap;
If you take a pointer to a local variable, it will point to an entry on the stack. You don't need to and shouldn't deallocate that memory yourself. The memory is "freed" by changing the stackpointer automatically when your variable runs out of scope (at the end of the function).
void myFunction() {
int localVariable;
int *pointerToLocalVariable = &localVariable;
// forbidden and unnecessary:
//delete pointerToLocalVariable;
// here (end of the block) the memory on the stack
// will be freed automatically
}
Since I got the same error after Norton-Interception in totally different contexts, this seems to be a case of Code::Blocks Norton incompatibility.