Lazy_pointer reset and operator-> problem

I have created miniature simulation of large project in which lambda, lazy_ptr features are used.
In the following code, reset() of lazy_ptr is used to update the function object. However during reset(), obj (unique_ptr) gets to nullptr. But subsequent code uses operator-> to call typename T*'s function. But operator-> crashes because obj is null.
I see it works on larger project and even though that project’s reset is also setting obj to null. but not on my??? I am just wondering what and how could it be possible?

[codebyte]

#include
#include
#include
#include
#include “test.h”

/*void f1(void) {
std::cout << “f1…” << std::endl;
return;
}
void f2(void) {
std::cout << “f2…” << std::endl;
return;
}
*/
void c1::c1_f1(void) {

//auto queue_lambda = [this]() {... };

auto f1_lambda = [this]() {
    std::cout << "f1_lambda entered." << std::endl;
    //c1 c1local;
    //return c1local;
    q1 * q1_ptr;
    q1_ptr = new q1();
    return q1_ptr;
};

c1_q1[0].reset(f1_lambda);
std::cout << "&c1_q1[0]: " << &c1_q1[0] << std::endl;
//c1_q1[0]->print_q1();
c1_q1[0];

}

int main() {

// lazy pointer, pass c1 class, name c1_lazy with 3 array members. o

// create standard function based on f1 named f1_std.
//std::function<void(void)> f1_std = f1;

// instantiate c1.

c1 c1i;
c1i.c1_f1();

}

test.h
#include
#include
#include
#include
#include

template class lazy_ptr {
private:
mutable std::unique_ptr obj;
mutable std::function<T*(void)> func;
public:
lazy_ptr() {}

explicit lazy_ptr(std::function<T*()> Constructor) { Init(Constructor); }
lazy_ptr(lazy_ptr&& rhs) {
std::cout << “lazy_ptr: explicit constructor entered.” << std::endl;
obj = std::move(rhs.obj);
func = std::move(rhs.func);
}

lazy_ptr& operator=(lazy_ptr&& rhs) {
std::cout << “lazy_ptr: operator=() entered…” << std::endl;
obj = std::move(rhs.obj);
func = std::move(rhs.func);
}

lazy_ptr(lazy_ptr&) = delete;
lazy_ptr& operator=(lazy_ptr&) = delete;

void reset(std::function<T*()> Constructor = nullptr) {
std::cout << "lazy_ptr reset(std::function<T*()> Constructor = nullptr) (replacing function with new func) " << &Constructor << std::endl;
Constructor==nullptr ? std::cout << “lazy_ptr reset(): constructor is NULL” << std::endl :
std::cout << "lazy_ptr reset(): constructor: " << &Constructor << std::endl;

//std::cout << "obj: " << obj << ", func: " << func << std::endl;
obj.reset();
func = Constructor;

obj==nullptr ? std::cout << "obj is null" << std::endl : std::cout << "obj is not null, ok" << std::endl;

}

void reset(T* ptr) {
std::cout << “GG:lazy_ptr reset(T* ptr) (resetting func to null)” << std::endl;
obj.reset(ptr);
func = nullptr;
}
bool operator==(T* rhs) const {
std::cout << “lazy_ptr: operator==() entered…” << std::endl;
return obj.get() == rhs;
}
bool operator!=(T* rhs) const {
return obj.get() != rhs;
std::cout << “lazy_ptr: operator!=() entered…” << std::endl;
}

const std::unique_ptr& operator->() const {
//make(true);
std::cout << “lazy_ptr: operator->() entered…” << std::endl;
assert(obj != nullptr && “Null dereference through lazy_ptr.”);
return obj;
}

std::unique_ptr& operator*() {
std::cout << “lazy_ptr: operator* entered…” << std::endl;
//make(true);
return obj;
}

const std::unique_ptr& operator*() const {
std::cout << “lazy_ptr: const…operator*() entered…” << std::endl;
//make(true);
return obj;
}

/*

  • Ensures that the object is created or is being created.
  • This is useful when early construction of the object is required.
    */
    void touch() const {
    std::cout << “lazy_ptr: touch() entered…” << std::endl;
    //make(false);
    }

// Tells if the lazy object exists or not.
/*
bool empty() const {
std::atomic_thread_fence(std::memory_order_acquire);
return obj == nullptr;
}/
std::unique_ptr getObj() {
std::cout << “lazy_ptr: getObj() entered…” << std::endl;
return obj;
}
std::function<T
(void)> getFunc() {
std::cout << “lazy_ptr: getFunc() entered…” << std::endl;
return func;
}

// Separated from make to improve inlining.
/*
void make_body(bool block) const {
if (block) {
lock.Acquire();
} else if (!lock.Try()) {
return;
}
MAKE_SCOPE_GUARD(& { lock.Release(); });
if (func == nullptr) return;
T* ptr = func();
obj.reset(ptr);
std::atomic_thread_fence(std::memory_order_release);
func = nullptr;
}

__forceinline void make(bool block) const {
if (!created()) {
make_body(block);
}
}
*/
};

class q1 {
private:
public:
void print_q1() { std::cout << “print_q1() entered…” << std::endl; }
int * q1a;
};

class c1 {
private:
lazy_ptr c1_q1[3];
public:

c1() { std::cout << "c1::c1() constructor entered..." << std::endl; }
//void c1_f1(void) { std::cout << "c1::f1() entered... " << std::endl; }
void c1_f1(void);

};