What I know, returning a reference to a local variable is the same as returning pointer to local variable and this causes memory leak in C++.
But does this apply to data members?
The code:
class MyClass
{
public:
std::string& getId();
private:
std::string id;
};
MyClass std::string& getId()
{
return id;
}
int main()
{
MyClass* c = new MyClass;
std::string brokenRef = c->getId();
// or may be std::string& brokenRef = c->getId();
delete c;
cout << brokenRef << endl; // <<< this should be a ref to unknown location, correct?
}
Thanks.
Yes, it applies. Even though your MyClass instance is not strictly local to main, but dynamically allocated and deallocated before the reference. Has the same effect, though.
The code as it stands is correct, because you copy the string while it is valid. The commented-out reference version is truly a broken reference.
In line
std::string brokenRef = c->getId();
You create a new instance of string and intialize it with a string referenced by reference returned by getId(). From this point on brokenRef lives completely independent life from MyClass object. Therefore brokenRef happily outlived MyClass object you destroyed.
You could have achieved desired affect by assigning reference to a reference variable:
std::string& brokenRef = c->getId();
In addition to this, I think you mixed terms memory leak and dangling pointer (dangling reference). Returning a pointer or a reference of a member does not cause memory leaks. But using them (dereferencing) after object is destroyed (so memory where members used to be stored is freed and they are becoming dangling) causes undefined behaviour and very likely crash.
It's okay in your example, because you assign to string, if you turn it into string& then it will be invalid as soon as you delete c.
(and it doesn't exactly cause memory leak).
as long as your MyClass is not deleted the reference is valid.
or if you would have declared it as a stack variable then as long as its in scope the members in the class instance are valid.
You will get some value but it will be some random value that as the object that contains it has been destroyed.
ideally I would delete and set that to null
so in your e.g.
c=null;
Object Oriented C++ has same object lifetime constraints as every OO based language
The life-cycle for an object begins when it is created, and ends whenit is destroyed. In a C++ class definition, a member function with thesame name as the class is a constructor. This is a function whichis called automatically whenever an instance of the class is created. Constructorsare typically used to initialize the data members of the object to theirdefault state, but may also be used to allocate resources (memory, files,etc.). For any class, a number of constructor functions may be declared,each taking different types of arguments, providing different ways of initializinginstances. A default constructor for a class is a constructor ofthat class that can be called without any arguments. A default constructorfor a class will be automatically generated if no constructor has beenexplicitly declared for that class. A copy constructor for a classis a constructor that can be called to copy an object of that class (ithas a single argument of the corresponding type). A copy constructor iscalled when, for example, an argument object is passed by value to a function,or when an object is initialized with the value of another object. A copyconstructor for a class will be automatically generated if no copy constructorhas been explicitly declared for that class. A member function with thesame name as the class with a leading tilde (~) is a destructor.This is a function that is called automatically when the object is deleted.The destructor is typically used to deallocate any memory allocated forthe object (and may also release any other resources acquired during construction).Constructors and destructors are not required in class definitions.
There are several ways to create objects in a C++ program. One is todefine a variable as being of a particular class, either as a global variableor as a local variable within a block. When the declaration is encounteredduring program execution, space is allocated for the object and the constructor,if any, for the object is called. Similarly, when an object variable goesout of scope, its destructor is called automatically. Another way to createan object is to declare a variable that is a pointer to the object classand call the C++ new operator, which will allocatespace for the object and call the constructor, if any, for the object.In this case, the pointer variable must be explicitly deallocated withthe delete operator. The constructor for theobject is executed when new is called, andthe destructor is executed when delete is called.An object can also be constructed by the explicit use of a constructorin an expression.
When a class is derived from another class, it inherits its parent class'constructor and destructor. Parent constructors are invoked before derivedconstructors. Destructors are invoked in the opposite direction, proceedingfrom the derived class upward through its parent chain.
More here http://www.objs.com/x3h7/cplus.htm
Related
Take this code for example:
class MyClass
{
public:
~MyClass()
{
cout << "Destructor called\n";
}
};
int main()
{
MyClass Testvar;
// destructer called for this
MyClass *ptrvar;
ptrvar = &Testvar;
// but not for this
}
It brings a lots of confusions to me. The code above prints:
Destructor called
only once. I declared two MyClass instances inside main, one of them is a normal variable of type MyClass, and other is a pointer of same type pointing to the normal variable. There is no need of destructor here (no dynamic allocations) but I defined one in the class for a sake of example. So, because two class instances are defined, the destructor should be called twice. But that doesn't happened when I run this code. If I remove the pointer and define one more normal instance, the program prints:
Destructor called
Destructor called
My observation is that destructors are not implicitly called when a pointer instance goes out of scope. Am I right or just missing something.
I declared two MyClass instances inside main
No you didn't. You declared an instance of MyClass and you created a pointer to that instance. That's all.
The behavior of your code is correct.
My observation is that destructors are not implicitly called when a pointer instance goes out of scope. Am I right or just missing something.
That's right. C++ does not provide a garbage collector. You have to keep track of your pointers by yourself. You can use the smart pointers to do so.
You have created only one object and only for that object the destructor is called.
The pointer do not instantiate another object, it simply points to the previous one
Destructors are called when an object allocated on the stack goes out of scope and when object dynamically created (with operator new) are explicitly destroyed (operator delete)
You only actually instantiated one object of type MyClass. That happened in this line:
MyClass Testvar;
In the following line, you only declared a pointer to an object of type MyClass, but this does not create a new object:
MyClass *ptrvar;
And in this line you assigned the address of your first MyClass to your pointer:
ptrvar = &Testvar;
So the pointer is addressing the very same object, you still have only one instance of MyClass. When the scope closes, TestVar is deleted, and you see the destructor called once.
You could have created a new MyClass object (on the heap) and assigned its address to your pointer like this:
MyClass *ptrvar = new MyClass();
Now you really do have two MyClass objects. However, when the scope closes you'll still see only one object being deleted. This is because new creates an object on the heap rather than on the stack, and such objects are not automatically deleted at the end of the scope in which they are created. You have to do this manually using delete:
delete ptrvar;
When this line executes, you'll see your destructor is called. If you don't do this you've left your object on the heap, and have "leaked" the memory it occupies.
To save having to do all of this manually, you should make use of the in-built smart pointers that C++ provides.
I have the following codes to dynamically allocate a class object in a function call:
#include <iostream>
class A
{
public:
A(){std::cout<<"Constructing..."<<std::endl;}
~A(){std::cout<<"Deconstructing..."<<std::endl;}
};
A & f()
{
std::cout<<"Calling f()"<<std::endl;
A * pa = new A();
std::cout<<"End calling f()"<<std::endl;
return *pa;
}
int main()
{
A & b = f();
}
The output are:
Calling f()
Constructing...
End calling f()
which means that the class object was never deleted.
However, if I change the line in main to:
A b = f();
the outputs are:
Calling f()
Constructing...
End calling f()
Deconstructing...
which means the class object was deleted automatically.
Why that assigning a reference to a non-reference will change its dynamic behavior?
There's no change to the dynamic object created by new. That's not destroyed in either case, since it can only be destroyed by explicit use of delete.
In the second case, you create a second object b by copying the dynamic object. Being automatic, that is destroyed when it goes out of scope, so you see a Deconstructing... message from that.
Since it was initialised by a copy constructor, not the default constructor, you don't see a corresponding Constructing... message. You could add a copy constructor to see that:
A(A const &){std::cout<<"Copying..."<<std::endl;}
giving the output
Calling f()
Constructing...
End calling f()
Copying...
Deconstructing...
In general, always use smart pointers and other RAII types to manage dynamic resources, to avoid memory leaks and other lifetime confusion issues.
In the case of
A & b = f();
b refers to the object created on the heap.
In the case of
A b = f();
b creates a copy (possible move) of the data on the heap. This one is destructed when the function exits (when b goes out of scope).
The object on the heap is left alone, in both cases.
To explore this further, the addition of the copy constructor would help A(A const&) and then printed a message, or even making it private and noting the compilation errors aid in marking the copies and their locations.
Note: when you new an object in a function and then don't destroy it, or don't move the pointer to some other owner, you will leak memory. Favour library utilities like unique_ptr or share_ptr to manage the resource (RAII).
When you declare a value type, it is constructed on the stack and the compiler takes care of calling its destructor when it goes out of scope. However, when you create the instance on the heap by calling new, the compiler can't know when the instance is not needed any more and therefor it's up to the programmer to indirectly call its destructor by using delete. The fact that you have a reference to the object on the heap doesn't provide the compiler with any knowledge of when the object has to be destroyed.
string * str=new string;
delete str;
when I delete 'str' which points to an object, do two destructors get called - one for the pointer itself, and one for the object it points to?
What would the pointer's destructor do?
delete just causes the object that the given pointer is pointing at to be destroyed (in this case, the string object. The pointer itself, denoted by str, has automatic storage duration and will be destroyed when it goes out of scope like any other local variable.
Note, however, that non-class types do not have destructors. So even when you use delete with non-class types, no destructor is called, but when the pointer goes out of scope, it gets destroyed as normally happens with any other automatic variable (means the pointer just reaches the end of its lifetime, though the memory pointed to by the pointer is not deallocated until you use delete to explicitly deallocate it.).
The pointer it self doesn't been destructed by the delete statement. but as any scope variable it's been destroyed when the scope ends.
Example:
void Function()
{
string * str=new string;
delete str; // <-- here the string is destructed
} // <-- here the pointer is "destructed", which is mean it's memory freed from the stuck but no actual destruction function is called..
The concept of destructor is applicable only to objects (i.e. entities defined with class or struct), not to plain types, like a pointer is. A pointer lives just like a int variable does.
when I delete 'str' which points to an object, do two destructors get called - one for the pointer itself, and one for the object it points to?
No. delete takes a pointer argument. It destroys the object that's pointed to (using its destructor, if it has one, and doing nothing otherwise), and deallocates the memory that's pointed to. You must previously have used new to allocate the memory and create the object there.
The pointer itself is not affected; but it no longer points to a valid object, so you mustn't do anything with it. This is sometimes known as a "dangling pointer".
What would the pointer's destructor do?
Nothing. Only class types have destructors.
The destructor for a raw pointer, like your example of std::string*, is trivial (just like the destructors for other primitive types: int, double, etc.)
Smart pointer classes have non-trivial destructors that do things like free resources, adjust reference counts, etc.
I like the simplification you get from the notion that every type has a destructor. That way you don't have a mental glitch with a template that explicitly destroys a stored value, even if the type of that stored value is an int or a pointer:
template <class T> struct wrapper {
unsigned char data[sizeof(T)];
wrapper(T t) { ptr = new (data) T; }
~wrapper() { (T*)&data->~T(); } // ignore possible alignment problem
wrapper<int> i(3);
However, the destructors for ints and pointers are utterly trivial: they don't do anything, and there is no place you can go to see the definition of the destructor, because the definition doesn't exist. So it's also reasonable to say that they don't have destructors.
Either way, when a pointer goes out of scope it simply disappears; no special code runs.
First i am from JAVA.
In java we create class object like this.
Example example=new Example();
The Example class can have constructor or cannot have constructor.
I can use the same in c++ like this
Example* example=new Example();
Where constructor is compulsory.
From this tutorial http://www.cplusplus.com/doc/tutorial/classes/
I got that we can create object like this.
Example example;
Which do not require an constructor.
I have two questions.
What is the difference between both the way of creating class objects.
If I am creating object like Example example; how to use that in an singleton class.
like I usually do like this.
Sample* Singleton::get_sample() {
if (sample == NULL) {
sample = new Sample();
}
return sample;
}
Please guide me if I am wrong.
I can use the same in c++ like this [...] Where constructor is compulsory. From this tutorial I got that we can create object like this [...] Which do not require an constructor.
This is wrong. A constructor must exist in order to create an object. The constructor could be defined implicitly by the compiler under some conditions if you do not provide any, but eventually the constructor must be there if you want an object to be instantiated. In fact, the lifetime of an object is defined to begin when the constructor routine returns.
From Paragraph 3.8/1 of the C++11 Standard:
[...] The lifetime of an object of type T begins when:
— storage with the proper alignment and size for type T is obtained, and
— if the object has non-trivial initialization, its initialization is complete.
Therefore, a constructor must be present.
1) What is the difference between both the way of creating class objects.
When you instantiate object with automatic storage duration, like this (where X is some class):
X x;
You are creating an object which will be automatically destroyed when it goes out of scope. On the other hand, when you do:
X* x = new X();
You are creating an object dynamically and you are binding its address to a pointer. This way, the object you created will not be destroyed when your x pointer goes out of scope.
In Modern C++, this is regarded as a dubious programming practice: although pointers are important because they allow realizing reference semantics, raw pointers are bad because they could result in memory leaks (objects outliving all of their pointers and never getting destroyed) or in dangling pointers (pointers outliving the object they point to, potentially causing Undefined Behavior when dereferenced).
In fact, when creating an object with new, you always have to remember destroying it with delete:
delete x;
If you need reference semantics and are forced to use pointers, in C++11 you should consider using smart pointers instead:
std::shared_ptr<X> x = std::make_shared<X>();
Smart pointers take care of memory management issues, which is what gives you headache with raw pointers. Smart pointers are, in fact, almost the same as Java or C# object references. The "almost" is necessary because the programmer must take care of not introducing cyclic dependencies through owning smart pointers.
2) If i am creating object like Example example; how to use that in an singleton class.
You could do something like this (simplified code):
struct Example
{
static Example& instance()
{
static Example example;
return example;
}
private:
Example() { }
Example(Example const&) = delete;
Example(Example&&) = delete;
Example& operator = (Example const&) = delete;
Example& operator = (Example&&) = delete;
};
Example example;
This is a declaration of a variable named example of type Example. This will default-initialize the object which involves calling its default constructor. The object will have automatic storage duration which means that it will be destroyed when it goes out of scope.
Example* example;
This is a declaration of a variable named example which is a pointer to an Example. In this case, default-initialization leaves it uninitialized - the pointer is pointing nowhere in particular. There is no Example object here. The pointer object has automatic storage duration.
Example* example = new Example();
This is a declaration of a variable named example which is a pointer to an Example. This pointer object, as above, has automatic storage duration. It is then initialized with the result of new Example();. This new expression creates an Example object with dynamic storage duration and then returns a pointer to it. So the example pointer is now pointing to that dynamically allocated object. The Example object is value-initialized which will call a user-provided constructor if there is one or otherwise initialise all members to 0.
Example* example = new Example;
This is similar to the previous line. The difference is that the Example object is default-initialized, which will call the default constructor of Example (or leave it uninitialized if it is not of class type).
A dynamically allocated object must be deleted (probably with delete example;).
There is two ways to make/create object in c++.
First one is :
MyClass myclass; // if you don;t need to call rather than default constructor
MyClass myclass(12); // if you need to call constructor with parameters
Second one is :
MyClass *myclass = new MyClass();// if you don;t need to call rather than default constructor
MyClass *myclass = new MyClass(12);// if you need to call constructor with parameters
In c++ if you use new keyword, object will be stored in heap. it;s very useful if you are using this object long time of period and if you use first method, it will be stored in stack. it can be used only short time period. Notice : if you use new keyword, remember it will return pointer value. you should declare name with *. If you use second method, it doesn;t delete object in the heap. you must delete by yourself using delete keyword;
delete myclass;
1) What is the difference between both the way of creating class objects.
a) pointer
Example* example=new Example();
// you get a pointer, and when you finish it use, you have to delete it:
delete example;
b) Simple declaration
Example example;
you get a variable, not a pointer, and it will be destroyed out of scope it was declared.
2) Singleton C++
This SO question may helps you
First of all, both cases calls a constructor. If you write
Example *example = new Example();
then you are creating an object, call the constructor and retrieve a pointer to it.
If you write
Example example;
The only difference is that you are getting the object and not a pointer to it. The constructor called in this case is the same as above, the default (no argument) constructor.
As for the singleton question, you must simple invoke your static method by writing:
Example *e = Singleton::getExample();
1)What is the difference between both the way of creating class
objects.
First one is a pointer to a constructed object in heap (by new).
Second one is an object that implicitly constructed. (Default constructor)
2)If i am creating object like Example example; how to use that in an
singleton class.
It depends on your goals, easiest is put it as a member in class simply.
A sample of a singleton class which has an object from Example class:
class Sample
{
Example example;
public:
static inline Sample *getInstance()
{
if (!uniqeInstance)
{
uniqeInstance = new Sample;
}
return uniqeInstance;
}
private:
Sample();
virtual ~Sample();
Sample(const Sample&);
Sample &operator=(const Sample &);
static Sample *uniqeInstance;
};
Example example;
Here example is an object on the stack.
Example* example=new Example();
This could be broken into:
Example* example;
....
example=new Example();
Here the first statement creates a variable example which is a "pointer to Example". When the constructor is called, memory is allocated for it on the heap (dynamic allocation). It is the programmer's responsibility to free this memory when it is no longer needed. (C++ does not have garbage collection like java).
In the first case you are creating the object on the heap using new.
In the second case you are creating the object on the stack, so it will be disposed of when going out of scope.
In C++ you'll need to delete objects on the heapexplicitly using delete when you don't Need them anymore.
To call a static method from a class, do
Singleton* singleton = Singleton::get_sample();
in your main-function or wherever.
Hi I have a question about this pointer, when an object is constructed, when it is initialized? Which means, when can I use it? The virtual table is constructed in the constructor, is the same with this pointer?
For example, I have a code like this. The output is 8. Does it mean that before the constructor is entered, this pointer is already initialized?
class A{
public:
A() { cout<<sizeof(*this);}
int i;
int *p;
};
int main() {
A a;
}
If it is true, what else would happen before the constructor is entered ?
If it is not true, when is the this pointer initialized ?
The this pointer isn't a member of the object or class - it's an implicit parameter to the method that you call. As such it's passed in much like any other parameter - except that you don't directly ask for it.
In your example above, the constructor is a special method, which is in turn a special kind of function. When you construct the object, the compiler allocates memory for it (in this case on the stack, as a is a local variable in the main function. Then it automatically calls the constructor to initialise the object.
As part of calling the constructor, the implicit parameter this - a pointer to your object - is passed in as a parameter.
In a method with the following signature...
void MyMethod (const int* p) const;
there are actually two parameters, both pointers. There's the explicit parameter p and the implicit parameter this. The const at the end of the line specifies that this is a const pointer, much as the earlier one specifies that p is a const pointer. The need for that special syntax only exists because this is passed implicitly, so you can't specify const-ness in the normal way as with other parameters.
A "static" method doesn't have the implicit "this" parameter, and cannot directly access the object members either - there may not be a particular object associated with the call. It is basically a standard function rather than a method, except with access to private members (providing it can find an object to access).
As Steve Fallows points out, sizeof (this) is known at compile-time, because it is a pointer type and all pointers (*1) have the same sizeof value. The "8" you see implies you are compiling for a 64-bit platform. this is usable at this point - it points to valid memory, and all the members have completed their constructor calls. However, it isn't necessarily fully initialised - you are still in the constructor call after all.
EDIT
*1 - strictly, that may not be true - but the compiler knows what type of pointer it's dealing with here even though the value isn't known until runtime.
The this pointer is not stored. When the constructor is called for an object that occupies a specific memory location, that location is passed as a parameter to the constructor and other member functions.
If this would be stored inside the object, how to retrieve that pointer? Right, you would again need the this pointer :)
sizeof(*this) is known at compile time. So the cout statement reveals nothing about the initialization of this.
Given that the constructor can immediately begin accessing members of the object, clearly this is initialized before the constructor begins.
What else happens before the constructor? Well could be anything. I don't think the standard limits what a compiler could do. Maybe you should specify anything you're thinking might happen.
The virtual table is constructed in the constructor, is the same with this pointer?
The virtual table is NOT constructed in the constructor.
Typically, a single global v-table is shared by all instances of the same class, and each individual class has its own global v-table.The v-table is known at compile-time, and "constructed" at program load time.
The this pointer is "constructed" (I think "allocated" is a better term) at allocation time, that is, after the global new operator is called, and before the constructor is entered.
In cases where the object is stack-allocated instead of heap-allocated, global new is not called, but this is still available as a result of allocating stack-space, which is just before the constructor is entered.
The instance vptr is assigned after the object's memory is allocated, and just before the constructor is called.
Does it mean that before the constructor is entered, the this pointer is already initialized?
Yes, the value of the this pointer is known before the constructor is even called. This value is available via the this keyword inside constructors, constructor initialization lists, destructors, member methods. The this keyword behaves on the surface as a method variable (of pointer type) but is not one; it typically sits in a register (ecx on x86 platforms) and you typically won't be able to compile code like &this.
What else would happen before the constructor is entered
At least as far as the this pointer is concerned, the first thing that happens (unless using placement new) is the allocation of memory ultimately pointed to by this, be it on the stack (like in your example) or on the heap (using new.) At this point the this pointer is known. Then, either default constructors or explicitly specified constructors (via constructor initialization lists) are then called on the base classes (if any) and on your class non-POD member variables (if any). The class vtable pointer is also set before this point if your class contains virtual methods or destructor. Then, your class constructor body, if any, is invoked. (Constructor are called recursively, i.e. when a base class' constructor is called, the latter's base class constructors are called followed by non-POD member constructors, with the base class' vtable pointer being set, followed by the class' constructor body.)
The this pointer is the first argument to every call of the class, including the constructor.
When a class method is called, the address of the class is pushed onto the stack last (assuming cdecl calling convention here). This is read back into a register to use as the this pointer.
Constructors are in fact called as if they were ordinary member functions.
You cannot have a virtual constructor because the constructor is responsible for setting the vtable member.
As nobugz already pointed out, your example doesn't really mean much -- sizeof yields its results based on the type of the object you pass to it. It does not evaluate its operand at run-time.
That said, yes, this is initialized before entry to the ctor. Basically, the compiler allocates space for the object (on the stack if the object has automatic storage duration, or using ::operator new if it has dynamic storage duration). Upon entry to the ctor, the ctors for base classes (if any) have already run to completion. When your ctor is called, this gives the address of the memory that was allocated for the object.
this starts pointing to the current object and all members and base classes have been initialized before you enter the constructor body.
Therefore, you can hand out pointer to this in the initialization list, but the receiver should do nothing else other than storing it, because the pointed-at instance may not be fully constructed at the time.
#include <iostream>
class B;
class A
{
B* b_ptr;
public:
A(B* b);
};
class B
{
A a;
int i;
public:
B(): a(this), i(10) {}
void foo() const { std::cout << "My value is " << i << '\n'; }
};
A::A(B* b):
b_ptr(b) //Ok to store
{
b_ptr->foo(); //not OK to use, will access initialized member
}
int main()
{
B b;
}