Overwrite stack-allocated instance of a class - c++

Consider the following code:
class A{
public:
A(){};
};
int main(){
A a = A();
std::cout << &a << std::endl;
a = A();
std::cout << &a << std::endl;
return 0;
}
Both addresses are the same. The behavior that I expected was that the second call to A() would overwrite the variable a by creating a new instance of A, thereby changing the new address of a.
Why is this so? Is there a way to statically overwrite a that I am not aware of?
Thank you!

Why is this so?
Within the scope of its lifetime, a variable is exactly one complete object (except in the case of recursion in which case there are multiple overlapping instances of the variable). a here is the same object from its declaration until the return of the function.
I expected was that the second call to A() would overwrite the variable a by creating a new instance of A,
It did that.
thereby changing the new address of a.
It didn't do that. The temporary object created by A() had a new address, but that temporary object was destroyed at the end of that full expression. a remained where it had been, and you invoked its assignment operator with the temporary object as the argument.

The variable a is allocated on the stack. Its address is not going to change for the duration of the function. The first and the second instance of class A will be created in the space taken up but the variable.

Related

Is the heap-allocated object of a class alive after its scope but before calling its destructor in C++

EDITED: Let's say we don't call explicitely the destructor of a heap-based object (delete A). If the pointer that points to "A" goes out-of-scope, is there a way the dynamic object remain accessible? for e.g., in the following code, can "a" be still alive after if-closing }?
class A{
void itsmethod();
};
int main()
{
if (true){
A* a = new A;
}
//...here how can I use dynamically allocated object?
a->itsmethod();
}
EDIT: As it was responded, the simplest immediate way is defining the pointer outside of if statement, but I am just wondering if there is any other option to prolong lifetime of dynamic object? Accordingly what else "A" class should provide? For instance passing by reference? Or equipping the class with move constructor... These suggestions may be irrelevant, I would like to hear your feedback.
I wonder if the object "a" is still alive after if-closing }?
The object a, which is a pointer, is not alive after the closing } of the if statement. The object to which a points to is in memory but it is not accessible with the posted code.
To be able to access the object to which a points to, declare a before the if statement.
int main()
{
A* a = nullptr;
if (true)
{
a = new A;
}
if ( a != nullptr )
{
a->itsmethod();
}
}
No and Yes: yes because dynamic memory is not freed up automatically. No because the code doesn't compile because a is scoped to if block and you are trying to use it from outside.
class A{
public:
int x;
};
int main(){
A* ptrA = NULL;
if(true){
// Everything declared here is accessible only here whatever being dynamic or static.
ptrA = new A;
ptrA->x = 10;
int x;
}
if(ptrA){
std::cout << ptrA->x << std::endl; // 10
delete ptrA;
}
return 0;
}
You must free up memory always when you're done with it otherwise it is a memory leak.
Above x is declared inside the if block on the stack so when end of if block is reached x will be destructed.
The object created by the new expression (i.e. by new A) will continue to exist.
The pointer a itself, since it has passed out of scope, will cease to exist as far as your program is concerned.
The net effect is that the dynamically allocated object is "leaked". It continues to exist after the block but there is no pointer or reference to it.
If you do something like
int main()
{
A *b;
if (true)
{
A* a = new A;
b = a;
}
a->itsmethod(); // diagnosible error
b->itsmethod(); // will work correctly
delete b; // destroy dynamically allocated object
b->itsmethod(); // undefined behaviour
}
then a->itsmethod() will give a compiler diagnostic (since a no longer exists) but the first b->itsmethod() will use the object created by the new expression. The second b->itsmethod() will compile, but yield undefined behaviour, since it accesses an object that no longer exists (due to the preceding delete b).
This happens because the pointer b continues to exist and, within the enclosed block, is assigned the value from a. So it then contains the result of the new expression.
No. The object 'a' will not be accessible anymore since its scope belongs to the if statement. However, there still is a memory address containing that object. This is why its good to do 'garbage collection' in programming.
Let's consider this demonstrative program
#include <iostream>
struct A
{
const char *s;
std::ostream & operator ()( std::ostream &os = std::cout ) const
{
return os << s;
}
};
int main()
{
A *a1;
if ( true )
{
A *a2 = new A { "Hello, Sepideha" };
a1 = a2;
}
( *a1 )() << std::endl;
delete a1;
return 0;
}
Its output is
Hello, Sepideha
Here the object a1 that has the type A * has the outer-most block scope of the function main.
The object a2 has the block scope of the if statement. It is alive only within this block.
At the same time there is dynamically created unnamed object of the type A pointer to which is assigned to a2 and then to a1. This unnamed object will be alive until the operator delete for a pointer that points to the object will be called. That is its live-time does not depend on the block scope of the if statement.
Because the pointer a1 points to this unnamed object then the pointer can be used outside the if statement to access the unnamed object in the dynamic memory.
After the statement with the delete operator this unnamed object stops to exist. But the object a1 is still alive.

Recursive construction using the This pointer

This code compiles and runs. (Run at your own risk). When it runs, it endlessly prints "Constr beg" as could be predicted. My question is, does the recursion create one object or multiple objects? If multiple objects are being created, how does that happen when the 'this' pointer is being used as the constructor parameter?
#include <iostream>
using namespace std;
class A {
private:
A* m_p;
public:
A() = delete;
A(A* m_p) {
cout << "Constr beg" << endl;
m_p = new A{this};
cout << "Constr end" << endl;
}
~A() {
cout << "Destr beg" << endl;
if (m_p != nullptr) {
delete this;
}
cout << "Destr end" << endl;
}
};
int main()
{
// A a(A&);
A* pA{nullptr};
A b(pA);
return 0;
}
My question is, does the recursion create one object or multiple objects?
The recursion creates instances of your class without any condition to stop it. You'll end up with a stack overflow, most likely.
If multiple objects are being created, how does that happen when the 'this' pointer is being used as the constructor parameter?
You're never using the parameter in the constructor, so how could its value possibly affect anything?
The first line (A* pA{nullptr};) creates a pointer and assigns it the value nullptr, so isn't actually invoking the constructor at all. Consider e.g. unsigned foo{0}; or A* pA = nullptr;.
The second line creates a new object of type A named 'b', and passes nullptr as the argument to the constructor (but that's never used). Inside the constructor, another object of type A is used, and passed the address of the A object that was just created (i.e. the address of main()'s 'b'), which is again not used for anything. Since that in turn recursively creates new objects it probably never returns; but if it did, the address of that new object would be assigned to the argument m_p which would then be discarded when (if) the constructor returned.

explanation of c++ class instances behavor

I Can't properly understand what is exactly happening when class instances are creating and when an instances methods are invoking.
For example there's a folowing c++ code:
class A {
int a;
void print_my_a();
public:
A();
};
void A:: print_my_a() {
cout << a << '\n';
}
A::A(): a(10) {}
int main() {
A Aobj1 = A();
A Aobj2 = A();
Aobj1.print_my_a();
Aobj2.print_my_a();
return 0;
}
so the question is:
Do each Aobj1 and Aobj2 instance refer to only one print_my_a() method ? or they both have their own print_my_a()?
All functions are code, and all code in C++ is shared. However, it does not really make any difference, because the code cannot be modified anyway.
However, the local variables created during the runtime of each method, instance or static, are per invocation, so if you call the same method twice, concurrently or not, each method would have its own local variables.
What you see is only an abstraction over the layout of data and code in the executable. Functions have one copy in the code segment and are shared between objects.
The code for the method exists only once, but "this"-pointer "passed" to the method will be different.
If you rewrite print_my_a as follows, it gets much clearer:
void A::print_my_a() {
cout << this->a << '\n';
}
Hence:
Aobj1.print_my_a() will have this pointer pointing to Aobj1
and Aobj2.print_my_a() will have this pointer pointing to Aobj2.
An object owns it's own instance of data members. So a separate instance of int a is owned by both of your objects Aobj1 & Aobj2. The methods are not owned by the object, but they use the state of the object (the data member instances for the object) which has made the call.

C++ class instantiation theory

#include <iostream>
using namespace std;
class A {
public:
A() {
cout << "Default Ctor" << endl;
}
};
int main() {
A(); // <------- Problem
return 0;
}
It shows Default Ctor on console. My questions
Is is valid?
If so, how did it instantiate since I didn't use new or any object?
You are creating a new object with A().
Is is valid?
Yes it is.
If so, how did it instantiate since I didn't use new or any object?
new simply creates the object in dynamic memory. You're creating the object in automatic memory. Also, just because you didn't give the object a name, doesn't mean it isn't created.
Think of this:
int foo() { return 1; }
int main()
{
foo();
}
Leaving optimizations aside Did foo() actually return 1? Yes it did. Just that you're not using it.
EDIT:
Let's break it down a bit:
A(); //creates a temporary unnamed object in automatic storage
A a; //creates an object a of type A in automatic storage
A a(); //creates no object, but declare a function a returning A and taking no parameters
A a(A()); //these two are equivalent
A a = A(); //creates a temporary unnamed object and creates an object a in automatic storage
//using the compiler-generated copy constructor
A a;
a = A(); //creates an object a in automatic storage
//creates an unnamed temporary object and uses the compiler-generated assignment operator
//to assign it to a
A a = &A(); //invalid, &A() is the address of a temporary a, which is illegal
Is is valid?
Yes, It is valid
What exactly happens?
A();
Creates a temporary nameless object of the type A by calling its default no argument constructor but the object is destructed by the time the next statement is executed since.
If so, how did it instantiate since I didn't use new or any object?
You can create objects on the local/automatic storage or on dynamic storage depending on your usage.
When you use new objects are created on dynamic storage(heap), when you create a object as you have it is created on the local/automatic storage(stack).
So using new only determines where the object will be created not whether it will be created.
What are Temporary Nameless objects?
You do not always need to name an object to instantiate them.
For Ex:
While calling function, when you pass objects by value temporary nameless objects are created and automatically destroyed all the time.These are objects which do not have any name and hence cannot be explicitly referred through program but they do serve the purpose for which they were created.
In simple words,
You are creating a nameless temporary object on the local/automatic storage which does not exist once the statement completes execution.

calling function whose name is class name itself?

I do not know what methodology they use since the code base is huge.
It defined a class like this:
class ABC {
member_func(string c);
};
main() {
ABC("").member_func("this random string");
}
What is the missing code that would enable us to call ABC("");?
I did not see any object of that class created anywhere.
That simply constructs an object of type ABC, but doesn't initialize any permanent memory location with that object. I.e., the initialized object the call to the ABC constructor creates is a temporary, and is lost after the call since it is not constructed in a memory location that can be accessed after the call such as an automatic variable on the stack, a static memory location, etc. So the "missing" code to make a call like that usable in the "real-world" is to actual name an object that is constructed so that it can be accessed later... for example, something like ABC my_object(""); or ABC my_object = ABC("");.
UPDATE: In the updated code you've posted, what's taking place is again a temporary object of type ABC is being constructed, and then a non-static method of class ABC called member_func is being called on the temporary that was created by the call to ABC's constructor. Of course for this code to have any meaning in the "real world", that call to member_func would have to contain some side-effect that would be visible outside of the class instance (i.e., the class instance could be containing a data-member that is a pointer to some shared memory object that the call then modifies). Since though from the code sample you've posted there does not seem to be any side-effects from the call, it's for all intents and purposes a non-operation ... a temporary ABC class instance is created, it has a method called on the instance, and then any reference to the instance is lost since it was not constructed in a memory location accessible from the current scope of main().
class ABC
{
std::string d;
public:
ABC(std::string x) // For the ABC("").
{ d = x; }
void foo(std::string x) // For the foo("").
{ std::cout << d << std::endl << x << std::endl; }
};
int main()
{
ABC("This creates a temporary object.").foo("This calls foo().");
// Is the same as...
{
ABC obj("This creates another object.");
obj.foo("This calls obj.foo().");
} // obj is destroyed.
return(0);
}
Self explanatory... I hope. :)