How to safely copy a global object to a pointer - c++

I have a header class that contains a declaration of a inline variable that I'm using as a global variable. I want to make a copy of this variable every time I call a function.
globalitems.h
#ifndef GLOBALVAR_H
#define GLOBALVAR_H
struct Data {
int a;
Data(int ca) {
a = ca;
}
};
inline Data globaldata(3);
#endif
Otherclass.h
#include "globalitems.h"
void createPointerCopy() {
Data* tempPointer = &globaldata;
tempPointer->a = 30;
std::cout << tempPointer->a << std::endl;
std::cout << globaldata.a << std::endl;
}
int main() {
createPointerCopy();
return 0;
}
outputs
30
30
Whereas my desired output is
30
3
How can I make it so that createCopy() safely creates a copy of the globaldata object?

If I understand you well, what you want is not getting a pointer to your global object but you want to create a copy, that is:
void createPointerCopy() {
Data temp = globaldata;
temp.a = 30;
std::cout << temp.a << std::endl;
std::cout << globaldata.a << std::endl;
}

So, I think your problem is that both variables point to the same place in memory.
What you really tell compiler to do with:
Data* tempPointer = &globaldata;
is to take address of globaldata and assign it to tempPointer. Thus, by changing fields of tempPointer, you change fields globaldata. Or, in other words, (*tempPointer) becomes an alias to globaldata.
I see two options:
Data tempData = globaldata;
and provide copy constructor if necessary; Or just:
int tempVal = globaldata.a
Additionally, I think you may want to be introduced with Singleton pattern

Related

Is there a technical implementation in c++, the modification of struct members is to modify the bound data, and this binding relationship is dynamic?

For example, if I have global variables:
int a;
int b;
I define that I can return a struct, I hope the members of the structure are bound to the global variables, and my modification to the members of the structure is to modify the global a, b. The code like:
struct bind
{
int a;
int b;
}
Bind getBind()
{
Bind bind;
band to a; // could be other variable, e.g. c
band to b; // could be other variable, e.g. d
return bind;
}
Note that it is not a simple reference, I may want to return the struct bound to c,d the next time I invoke getBind().
Background introduction:
collect data scattered around as a struct in a caller-unaware
way.
can return a const struct, caller can't modify its member
avoid modify member inconsciently by copy obj
I'm very puzzled, for the underlying language of C++, this should be easy to implement, but there seems to be no such funcation. Maybe I don't know, I hope so and get the answer here.
You can use references:
#include <iostream>
int a,b,c,d;
struct Bind {
int& ref1;
int& ref2;
};
Bind getBind(bool flag){
if (flag) return {a,b};
else return {c,d};
}
// ... or ...
Bind getBind(int& a,int& b){
return {a,b};
}
int main() {
auto x = getBind(true);
x.ref1 = 42;
x.ref2 = 101;
auto y = getBind(false);
y.ref1 = 0;
y.ref2 = 1;
auto z = getBind(a,b);
std::cout << z.ref1 << " " << z.ref2 << "\n";
auto w = getBind(c,d);
std::cout << w.ref1 << " " << w.ref2 << "\n";
}
Output:
42 101
0 1
However, it is not quite clear what you want to achieve. Global variables are better to be avoided in the first place and using reference as memebrs has certain implications, though if thats what you want then maybe its just fine.

insertion into unordered_map got lost

I'm having the following code, but after run the code, the result is empty, any ideas why the result is empty? the reference of result in function main was passed to myclass, I thought function addToResult will actually add data to result, and I'm expecting a map key = "test", value = "1": "1". I'm kind of new to c++. Thanks!
#include <iostream>
#include <string>
#include <unordered_map>
using LookUpTable = std::unordered_map<std::string, std::string>;
using DLTable = std::unordered_map<std::string, LookUpTable>;
class MyClass
{
public:
MyClass(DLTable& dltable) {
m_dltable = dltable;
};
void addToResult() {
LookUpTable ee;
ee.emplace("1", "1");
m_dltable.emplace("test", ee);
};
private:
DLTable m_dltable;
};
int main ()
{
DLTable result;
MyClass myclass(result);
myclass.addToResult();
std::cout << "myrecipe contains:" << std::endl;
for (auto& x: result) {
std::cout << x.first << ": "<< std::endl;
for (auto& xx : x.second) {
std::cout << xx.first << ": " << xx.second << std::endl;
}
}
std::cout << std::endl;
return 0;
}
Let' look into simplified example:
int a = 0;
int &b = a;
int c = b;
c = 123;
Will last assignment modify a? Of course not. It does not matter how you pass value to c through reference or not c is completely independent variable that just initialized by a reference.
Your case is the same - m_dltable is separate variable and the fact you initialize it using reference does not change anything. (Your case even worse, you did not initialize it by reference, you assigned to it)
In general your approach is wrong. If you want directly access that variable then just make it public, do not try to create convoluted workarounds on how to access it. If you want incapsulation just create members that allow you to iterate over that container. For example return a const reference to it or have begin() and end() methods that return (const) iterators accordingly.

Trying to create object using constructor inside static function in C++

I was trying to create an object inside static function using a constructor.
Here is the code
class A {
public:
A() { this->a = 50; std::cout << "constructor called... " << this << std::endl; setAddr(this); }
~A() { this->a = 10; std::cout << "destructor called... " << this << std::endl; }
int a;
static A* addr;
static void setAddr(A* ad) { addr = ad; }
static A &create() { A(); return *addr; }
};
A* A::addr = NULL;
int main() {
A &ptr = A::create();
std::cout << "a = " << ptr.a << std::endl;
ptr.a = 100;
std::cout << "a = " << ptr.a << std::endl;
getch();
return 0;
}
I know using new is best way to do it,but i was trying to do it using contructor to know whether it can be done or not.
The output was:
constructor called... 009AF874
destructor called... 009AF874
a = 10
a = 100
Now here is my question,
1) why destructor is called when did not create an object using any declaration like A obj;
2) and if the destructor is called then how I am able to assign a value to otr.a;
By looking at the program's output I made the following conclusion.
1) I read somewhere that constructor is called after the memory has been allocated to object. And if an object is created then it has to be destroyed and the scope of the obj decided to destroy it now.
2) Since object address has previous values before destroying it and returns call return the address of the variable storing it. When I try to access it, I was able to do so because that memory address still exists.
That's not how you make a singleton. The statement
A();
creates a temporal object of class A that is destroyed (as per standard) at end of statement.
Indeed, memory is allocated before call of constructor. Resulting object can be assigned or passed by reference or value to any function of this statement, but in former case, reference is valid only until end of call expression. Exception is that if it was assigned to reference, its length of life is extended to one
of reference. After life of object ended, any access to memory it used results in UB, provided that it could be used by any other operations.
Any access to object after destructor was called is an UB as well.
Here is an example (this code intentionally contains UB)
#include <iostream>
class A {
public:
A() { this->a = 50; std::cout << "constructor called... " << this << std::endl; }
~A() { this->a = 10; std::cout << "destructor called... " << this << std::endl; }
int a;
static const A &create() {
const A& addr = A();
std::cout << "a = " << addr.a << std::endl;
return addr;
}
};
int main() {
const A &ref = A::create();
std::cout << "a = " << ref.a << std::endl;
return 0;
}
Note, that C++ allows to bind temporary only to const reference. There are way to work around that, but that's irrelevant.
Output of this program may vary, depending on compiler and level of optimization. E.g. clang with no optimization:
constructor called... 0x7ffc1f7991d0
a = 50
destructor called... 0x7ffc1f7991d0
a = 4202884
gcc may output 10 in last line. MS may crash on it. Keyword is "may", there is no rule that governs what would happen. Object stopped existing after create() returned reference to it because lifespan of addr came to end, and we are left with dangling reference.
Obviously we can extend lifespan of addr by making it static.
static const A &create() {
static const A& addr = A();
std::cout << "a = " << addr.a << std::endl;
return addr;
}
Static variable in function's scope will be created at first call of function and stops to exist when process stops.
constructor called... 0x6031b8
a = 50
a = 50
destructor called... 0x6031b8

C++ confusion with new and scope

I am trying to learn C++ and from what I've read in books and on SO:
If I use auto x = new Object(); x is a pointer to address of Object and this is in dynamic memory and exists until I delete it.
However if I use Object x; or auto x = Object() it only lasts until it goes out of scope.
In an example they have shown this:
void foo()
{
Point p = Point(0,0);
} // p is now destroyed.
What I don't understand is what happens when I return a object when I don't use new? Will it be a copy of the object?
Here is an example of what I am not sure about:
class Object
{
public:
int X;
static Object Foo(int y)
{
Object result;
result.X = y;
return result;
}
};
class TestContainer
{
public:
void Run()
{
for(auto i = 0; i < 10; i++)
{
_objects.at(i) = Object::Foo(i + (rand() % 10 + 1));
}
}
private:
std::vector<Object> _objects;
};
void main()
{
TestContainer tc;
while(true)
{
tc.Run();
}
}
Note I haven't tested this code but I think it illiterates my confusion. In my main function I instantiate TestContainer and endless call it's Run method. This in turn loops calling a static Foo method on Object that returns a copy of a new Object, which is stored in a vector.
My question is, what happens with all the Object's? If I replace element 2 in the objects vector with a new Object, is the old value now "out of scope" and is deleted?
Will it be a copy of the object?
Yes.
Or a move could be used instead, or the entire thing could be optimised away to produce only one actual object in your final, compiled program.
But, basically, yes.
If I replace element 2 in the objects vector with a new Object, is the old value now "out of scope" and is deleted?
Yes.
As an aside, you're using at on elements that don't exist; to add elements, use insert or push_back.
A simple class like this behaves much like a POD variable. o1=o2 copies the fields, element-wise. So the target Object of an assignment does not get deleted but overwritten.
Objects which go out of scope "go away" (because the stack is unwound) like e.g. an int.
Here is a run-able example that I believe illustrates this behavior:
#include <iostream>
using namespace std;
class Foo {
private:
int id;
public:
Foo(int x)
: id(x)
{
cout << this->id << " is created" << endl;
}
Foo(const Foo& rhs)
: id(rhs.id)
{
cout << "copied " << this->id << endl;
}
Foo& operator=(Foo rhs){
this->id=rhs.id;
cout << "assigned " << this->id << endl;
return *this;
}
~Foo(){
cout << this->id << " is destroyed" << endl;
}
int getID(){
return this->id;
}
};
Foo bar(){
Foo f1 = Foo(1);
cout << f1.getID() << " from bar" << endl;
return f1;
}
int main(){
Foo f2 = bar();
cout << f2.getID() << " from main" << endl;
return 0;
}
This produces this output:
1 is created
1 from bar
1 from main
1 is destroyed
From this, I'm not seeing a copy or an assignment. I suspect what is happening is that both f1 and f2 are referencing the same instance of the object in memory. The object is not being de-allocated when the f1 reference goes out of scope because the object has another reference assigned to it.

Initialize POD struct

#include <iostream>
using namespace std;
struct POD
{
int i;
char c;
bool b;
double d;
};
void Func(POD *p) { ... // change the field of POD }
void ModifyPOD(POD &pod)
{
POD tmpPOD = {};
pod = tmpPOD; // first initialize the pod
Func(&pod); // then call an API function that will modify the result of pod
// the document of the API says that the pass-in POD must be initialized first.
}
int main()
{
POD pod;
ModifyPOD(pod);
std::cout << "pod.i: " << pod.i;
std::cout << ", pod.c: " << pod.c;
std::cout << " , pod.b:" << pod.b;
std::cout << " , pod.d:" << pod.d << std::endl;
}
Question> I need to design a function that modify the pass-in variable pod. Is the above function named as ModifyPOD correct? First, I initialize the struct by assigning it(i.e. pod) with the value from a local struct(i.e. tmpPOD). Then, the variable is passed to Func.
I use the local variable to initialize the pod so that I can avoid to do the following instead:
pod.i = 0;
pod.c = ' ';
pod.b = false;
pod.d = 0.0;
However, I am not sure whether this practice is legitimate or not.
Thank you
Yes, it is legitimate. I''ll just add that you can do
pod = POD();
Func(&pod);
in the ModifyPod() function which is equivalent and simpler.