Multiple calling constructor will change the member pointer address in C++ - c++

I write a program to check the init process of class creation, and found calling the constructor multiple times changed the member pointer address. Look at following snippet.
#include <iostream>
using namespace std;
class FF {
public:
FF(){
this->ptr = NULL;
value = 1;
cout << "ptr address in 1: " << this->ptr <<endl;
}
FF(const int* ptrcopy, const int valuecopy){
cout << "ptr address in 2: " << this->ptr << endl;
FF();
/* Is this equivalent with FF() ?
this->ptr = NULL;
value = 1;
*/
init(ptrcopy, valuecopy);
}
void init(const int* ptrcopy, const int valuecopy) {
cout << "ptr address in 3: " << this->ptr << endl;
if (this->ptr != NULL)
{
cout << "error happened, the address of ptr is " << this->ptr << endl;
return;
}
}
private:
int* ptr;
int value;
};
int main(){
int *ptr = new int(10);
int value = 1;
FF fclass(ptr, value);
delete(ptr);
return 0;
}
The output is
ptr address in 2: 0x400b40
ptr address in 1: 0
ptr address in 3: 0x400b40
error happened, the address of ptr is 0x400b40
It seems the calling of FF() only init the ptr to NULL in its space, and the ptr change back to original 0x400b40 after calling.
Can someone explain about it ?

Your call of FF(); will create a new, unnamed stack based FF object, construct it (generating the output you see), then immediately destroy it again (for which you don't show any output). This is why the ptr address seems to change back - because it never changed. Add in a destructor that prints out the address of this to see this occur.
Incidentally, your use of this->ptr in the second (parameterized) constructor is Undefined Behavior because you never assign a value to ptr.
If your intent is to call the default constructor from the parameterized constructor, and your compiler supports C++11, you can delegate to the default constructor.
FF(const int* ptrcopy, const int valuecopy): FF() { /* ... */ }

I think what's happening is that in constructor 2 you are printing the uninitialized value for ptr (0x400b40) and then you are creating a new object of type FF with FF(). Then constructor 1 will be called for the new object, it's ptr member will be changed to NULL (so when printed it will be 0). After the constructor for the new object finishes it returns to constructor 2 (the destructor for the previously object is called) and then you call init which will display the same value for ptr as before since this object's ptr member hasn't been changed.
It might help you to also print the something in the destructor. That would be FF::~FF().
EDIT: Spelling and destructor suggestion

Like 1201ProgramAlarm said, doing FF(); does not call the constructor of the current object. To do so, you would do something like below (assuming C++11):
class FF {
public:
FF() : ptr(nullptr), value(1) {
cout << "ptr address in 1: " << this->ptr <<endl;
}
FF(const int* ptrcopy, const int valuecopy) : FF() {
cout << "ptr address in 2: " << this->ptr << endl;
init(ptrcopy, valuecopy);
}
void init(const int* ptrcopy, const int valuecopy) {
...
}
...
};
See also this question.

Compare to the following:
class C
{
public:
C() { std::cout << 'c' }
~C() { std::cout << 'd' }
};
void test()
{
C f;
std::cout << 't';
}
You should know about already, you create a temporary object running out of scope at the end of the function. You should see output ctd
void test()
{
C();
std::cout << 't';
}
Same again, with a little difference: The object runs out of scope right after the statement is executed, so output would be cdt.
Now exactly the same happens in your constructor, you just create a temporary, separate FF object when calling FF() inside the constructor's body.
I suppose you instead intended constructor delegation (available since C++11); however, syntax is different:
FF(int const*, int)
: FF() // as if using the initialiser list
{ /* can do some extra work here */ }
Now, the default constructor will be called on this before entering the function body. Of course, works with any constructor, as long as called appropriately:
FF() : FF(nullptr, 0) { }
Now, the default constructor would call your second one.

Related

Why does rvalue object does not get moved to function with rvalue parameter?

I was wondering why std::move to a function with an rvalue parameter was not actually moving anything, but passing by reference instead?
Especially when I know it works for constructors.
I was running the following code:
#include <memory>
#include <iostream>
void consume_ptr(std::shared_ptr<int> && ptr) {
std::cout << "Consumed " << (void*) ptr.get() << std::endl;
}
int main(int argc, char ** argv)
{
std::shared_ptr<int> ptr = std::make_shared<int>();
consume_ptr(std::move(ptr));
if (ptr) {
std::cout << "ptr should be moved?" << std::endl;
}
return 0;
}
The output is:
ptr should be moved?
According to everything I've read, the std::shared_ptr should have been moved inside the function, meaning that the object ptr itself would hold nullptr after moving it into consume_ptr, but it doesn't!
I tried it with some custom class of mine with logging, and it looks like the move constructor is never even called.
It's reproducible under every compiler and optimization level.
Can anyone clear this up for me please?
std::move by itself does not actually move anything. That is to say, std::move alone does not invoke any move constructors or move-assignment operators. What it actually does is effectively cast its argument into an rvalue as if by static_cast<typename std::remove_reference<T>::type&&>(t), according to cppreference.
In order for any moving to actually happen, the moved object must be assigned to or used in the move-initialization of something else. For example, it could be used to initialize a member.
void something::consume_ptr(std::shared_ptr<int> && ptr) {
this->ptr = std::move(ptr);
std::cout << "Consumed " << (void*) ptr.get() << std::endl;
}
However, one way to make your pointer get moved without being assigned to anything is to simply pass it by value, causing your pointer to be moved into the parameter.
void consume_ptr(std::shared_ptr<int> ptr) {
std::cout << "Consumed " << (void*) ptr.get() << std::endl;
}
This way can actually be more useful than the rvalue way if you're going to end up assigning the parameter to something, because it allows you to pass stuff in by copy, too, and not just by move.
void consume_ptr_by_rvalue(std::shared_ptr<int> && ptr);
void consume_ptr_by_value(std::shared_ptr<int> ptr);
void do_stuff() {
std::shared_ptr<int> x = /*...*/;
std::shared_ptr<int> y = /*...*/;
// consume_ptr_by_rvalue(x); // Doesn't work
consume_ptr_by_rvalue(std::move(y)); // Risk of use-after-move
std::shared_ptr<int> z = /*...*/;
std::shared_ptr<int> w = /*...*/;
consume_ptr_by_value(z);
consume_ptr_by_value(std::move(w)); // Still risk, but you get the idea
consume_ptr_by_value(make_shared_ptr_to_something()); // Can directly pass result of something
}
Here:
void consume_ptr( std::shared_ptr<int>&& ptr )
{
std::shared_ptr<int> new_ptr { ptr }; // calling copy ctor
std::cout << "Consumed " << ( void* ) new_ptr.get( ) << '\n';
}
No move happens there. No call to a move ctor or a move assignment operator. That's just a simple pass by rvalue reference there.
Output:
Consumed 0x20d77ebe6a0
ptr should be moved?
Now take a look at this:
void consume_ptr( std::shared_ptr<int>&& ptr )
{
std::shared_ptr<int> new_ptr { std::move(ptr) }; // calling move ctor
std::cout << "Consumed " << ( void* ) new_ptr.get( ) << '\n';
}
int main( )
{
std::shared_ptr<int> ptr { std::make_shared<int>( ) };
consume_ptr( std::move(ptr) );
if ( ptr )
{
std::cout << "ptr should be moved?" << std::endl;
}
}
Output:
Consumed 0x21160bbdf40
See. The move operation happened. And the if's body did not run.

How do I return a pointer from a class member function e.g. size_t * class :: function(); and use a class destructor ~size_t*class::function();

I am at the point learning classes/destructors in c++ and the need to return a pointer from a class member:
size_t * classname :: function();
but it doesn't work.
My logic is to declare a class variable e.g. classname * p_p = classfunction(data); that should access the class member:
size_t * classname :: classfunction(data)
{
//... do something ...
new p_p;
return p_p;
}
So the pointer address in theory gets returned to the main() variable p_p each time the member function of the class gets called.
Or should but doesn't and the program crashes somehow but not even sure on which point.
There is no compiler warning or error and the
debugger doesn't stops anywhere and I find nothing on returning a pointer from a class member function at all nor that it isn't allowed or something.
Also if there IS a syntax to return a pointer from a class member function I would need to have a syntax for delete the "new p_p".
So my question is: Should it work and how would I get this running or why is that maybe it is not working or forbidden? In my logic it should be a proper way but I may be wrong somehow and classes doesn't support this function completely.
EDIT:
Thanks to your answers and comments I got the pointer returned from the class member. (Also changed size_t to int since its just a pointer.) Like you suggested in the comments I added a minimal reproducible example:
#include <iostream>
using namespace std;
//########## class without ~ destructor ##########
class classname
{
public:
int *ptr;
int *classfunction(int);
void delete_classfunction(int*);
};
void classname::delete_classfunction(int*ptr)
{
delete[] ptr;
ptr = nullptr;
}
int *classname :: classfunction(int value)
{
int* ptr = new int[value]; //no delete?
ptr[0] = 5;
return ptr;
}
//########## class with ~destructor ##########
class classname_c
{
public:
int *ptr;
int value;
*classname_c(int );
void print(int*);
~classname_c();
};
void classname_c::print(int* ptr)
{
cout << ptr[0] << " shows value" << endl;
}
*classname_c::classname_c(int value)
{
int* ptr = new int[value];
ptr[0] = value;
} /*Brings warning: control reaches end of non-void function [-Wreturn-type]
48 | }
| ^*/
classname_c::~classname_c ()
{
cout << ptr[0] << endl;
delete[] ptr;
ptr = nullptr;
cout << ptr[0] << endl;
}
int main()
{ //class and deleting it myself calling the function delte
int value = 3;
int *ptr;
classname call;
ptr = call.classfunction(value); //create new ptr
cout << ptr[0] << " shows value" << endl;
call.delete_classfunction(ptr); //free memory
cout << ptr[0] << " shows value succ. deleted" << endl;
//class with destructor
classname_c dest(value);
dest.print(ptr);
cout << ptr[0] << " shows value succ. deleted" << endl; //its not!
return 0;
}
brings the following output:
5 shows value
0 shows value succ. deleted //How it should be
3 shows value
3 shows value succ. deleted //but its not, why? What did I do wrong?
Press <RETURN> to close this window...
Now I am not sure if/when the ~destructor is working or how I can test if I created the destructor right, because the ptr value is not deleted.
Also can I fix the
warning: control reaches end of non-void function [-Wreturn-type]
48 | }
| ^
It is perfectly fine to return a pointer from a member function, although returning a pointer to an allocated size_t seem a bit overkill.
What you want is probably something like this:
#include <iostream>
class cls
{
public:
size_t *ptr_func();
};
size_t *cls::ptr_func()
{
size_t *p = new size_t(42);
return p;
}
int main()
{
cls c;
size_t *p = c.ptr_func();
std::cout << (void *)p << '\n';
std::cout << *p;
delete p;
}
This may not answer your question but it might illustrate why this is not working how you expect. When you call a member function of a class, i.e. classname::function(), you need to have an instance of that class on which to call it. Something which has been defined like
class classname {
public:
classname() {ptr = new int(0);}
size_t* function();
~classname();
int* ptr;
};
size_t* classname::classfunction() {
size_t* ptr = new size_t();
return ptr;
}
Cannot be called by
classname * p_p = classfunction();
because classfunction() is not being called on an instance of classname and because classname is not size_t so you can't assign classname to the return from a function which returns type size_t unless a cast from one to the other has been explicitly defined (same goes for classname* and size_t*). You can do something like this
classname cls;
size_t* ptr = cls.classfunction();
Also note that destructors are not used for member functions, only for classes, so the syntax ~size_t*class::function() doesn't really make sense.
If you are trying to get a pointer to a class instance you can simply do
classname * ptr = new classname();
and put your //... do something ... in a constructor.
Edit
The use of a destructor is to perform the
[...] necessary cleanup needed by a class when its lifetime ends.
This means that the destructor is called when the instance of said class goes out of scope or is manually deleted. So when you have a class defined as above, with the destructor
classname::~classname() {
delete ptr;
}
This means that ptr will be deleted when the instance of classname reaches the end of its "lifetime". E.g.
int main() {
classname* cls = new classname();
// cls->ptr == int(0)
delete cls; // Calls ~classname()
// cls->ptr == NULL
}
The same is true for stack allocation (classname cls();) and in either case the destructor would be called automatically at the end of main (if that instance had not already been manually deleted).
Now what you can't do is delete a pointer that was allocated outside the class instance - if you want to be able to control a pointer like that while still having it accessible from outside the class you can make it a public member, as I did in the edited class declaration. This allows you to access the pointer from outside the class and then still delete it with the destructor,
int main() {
classname* cls = new classname();
// cls->ptr == 0
cls->ptr = 3;
// cls->ptr == 3
delete cls;
// cls->ptr == NULL
}
Hopefully that offers some clarity.
The warning is because of the constructor
*classname_c::classname_c(int value) {//...}
.... don't do this until you really know what you're doing, if you want a pointer to an instance of the class the constructor should be
classname_c::classname_c(int value) {//...}
and you should create the instance with
classname_c* cls = new classname_c(value);

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

Why does un-named object returned by value get destructed before its conversion operator is called?

I have a function which returns an object by value. The recipient variable requires the outward conversion operator on that object to be called.
If I construct the returned object at the return statement (RVO) its destructor gets called before the outward conversion operator.
However, if I name the object, and return that, the outward conversion operator gets called before the object is destructed.
Why is that?
#include <iostream>
class Ref {
public:
Ref(int * ptr) : iptr(ptr) {
std::cout << "Ref Constructed at: " << long(this) << " Pointing to: " << long(ptr) << '\n';
}
Ref(Ref & ref) : iptr(ref) {
std::cout << "Ref Moved to: " << long(this) << '\n';
ref.iptr = nullptr;
}
operator int () {
std::cout << "Ref-To int: Temp at: " << long(iptr) << '\n';
return *iptr;
}
operator int* () {
std::cout << "Ref-To int*: Temp at: " << long(iptr) << '\n';
return iptr;
}
~Ref() {
delete iptr;
std::cout << "Ref at: " << long(this) << " Deleted: " << long(iptr) << '\n';
}
private:
int * iptr;
};
Ref foo() {
int * temp = new int(5);
Ref retVal(temp);
std::cout << "Return named Ref\n";
return retVal;
}
Ref bar() {
int * temp = new int(5);
std::cout << "Return anonymous Ref\n";
return Ref(temp);
}
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "********* Call foo() *************\n";
int result = foo();
std::cout << "\n********* Call bar() *************\n";
int result2 = bar();
return 0;
}
Output from this is:
********* Call foo() *************
Ref Constructed at: 2356880 Pointing to: 5470024
Return named Ref
Ref-To int*: Temp at: 5470024
Ref Moved to: 2356956
Ref at: 2356880 Deleted: 0
Ref-To int: Temp at: 5470024
Ref at: 2356956 Deleted: 5470024
********* Call bar() *************
Return anonymous Ref
Ref Constructed at: 2356680 Pointing to: 5470024
Ref-To int*: Temp at: 5470024
Ref Constructed at: 2356968 Pointing to: 5470024
Ref at: 2356680 Deleted: 5470024
Ref-To int: Temp at: 5470024
Press any key to continue . . .
When bar() is called the reference is deleted before the conversion operator is called, and it crashes.
Also, I don't understand why the Ref to int* conversion is getting called when the return value is being built.
What is going on
I don't understand why the Ref to int* conversion is getting called when the return value is being built.
That happens because, apparently, MSVC does not perform RVO in debug mode, so the "copy constructor" (Ref(Ref&)) gets called to return from the foo function and this gets executed:
Ref(Ref & ref) : iptr(ref) {
// ...
}
where iptr, of type int*, is initialized with the implicit conversion from ref.
As #bogdan made me notice, this "copy constructor" of yours really has a move constructor semantic, and you should probably write a specific Ref(Ref&&) for that instead.
In bar, we have that you are building an rvalue return Ref(temp) which cannot be bound to a lvalue reference for the Ref(Ref&) constructor, and therefore the other constructor is picked and the pointer in copied in (without resetting the temporary one).
When the temporary one gets out of scope, the pointer is deleted, and when the constructed object from bar also goes out of scope, the same pointer is deleted, causing undefined behaviour (which is the reason of your crash).
The C++ way to write that class
Your class has many other issues. For one it can lead to various crashes and it's generally not memory safe. In C++ you would write something like this for that class:
class Ref {
public:
explicit Ref(std::unique_ptr<int> ptr)
: iptr(std::move(ptr))
{}
int get() const { return *iptr; }
int* data() const { return iptr.get(); }
private:
std::unique_ptr<int> iptr;
};
or even just std::unique_ptr.
The point here is that implicit conversions and manual dynamic memory allocation will often lead to many bugs and "crashes". Avoid them like the plague as much as possible.

Copy Constructor

I am new to C++ programming, I got a doubt when I was reading a C++ regarding copy constructor. Why copy constructor will call when we pass object of class to a outside function as pass by value. Please go through my code as below.
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
class Line
{
public:
int getLength( void );
Line( int len ); // simple constructor
Line( const Line &obj); // copy constructor
~Line(); // destructor
private:
int *ptr;
};
// Member functions definitions including constructor
Line::Line(int len)
{
cout << "Normal constructor allocating ptr" << endl;
ptr = new int;
*ptr = len;
}
Line::Line(const Line &obj)
{
cout << "Copy constructor allocating ptr." << endl;
ptr = new int;
*ptr = *obj.ptr; // copy the value
}
Line::~Line(void)
{
cout << "Freeing memory!" << endl;
delete ptr;
}
int Line::getLength( void )
{
return *ptr;
}
void display(Line obj)//here function receiving object as pass by value
{
cout << "Length of line : " << obj.getLength() <<endl;
}
// Main function for the program
int main( )
{
Line line(10);
display(line);//here i am calling outside function
_getch();
return 0;
}
In the above the I am passing object of class as parameter and display function receiving it as pass by value. My doubt is when I pass object to a function which is not a member of class why copy constructor is calling. if I receive object as reference in display() function[i.e display(Line &Obj)] it is not calling the copy constructor. Please help me what is the difference.
When you pass something by value, the copy constructor is used to initialize the parameter that's passed -- i.e., what's passed is a copy of whatever you give, so of course the copy constructor is used to create that copy.
If you don't want the value copied, pass by (probably const) reference instead.