In C++ do you always have to initialize a pointer to an object with the new keyword?
Or can you just have this too:
MyClass *myclass;
myclass->DoSomething();
I thought this was a pointer allocated on the stack instead of the heap, but since objects are normally heap-allocated, I think my theory is probably faulty?
Please advice.
No, you can have pointers to stack allocated objects:
MyClass *myclass;
MyClass c;
myclass = & c;
myclass->DoSomething();
This is of course common when using pointers as function parameters:
void f( MyClass * p ) {
p->DoSomething();
}
int main() {
MyClass c;
f( & c );
}
One way or another though, the pointer must always be initialised. Your code:
MyClass *myclass;
myclass->DoSomething();
leads to that dreaded condition, undefined behaviour.
No you can not do that, MyClass *myclass will define a pointer (memory for the pointer is allocated on stack) which is pointing at a random memory location. Trying to use this pointer will cause undefined behavior.
In C++, you can create objects either on stack or heap like this:
MyClass myClass;
myClass.DoSomething();
Above will allocate myClass on stack (the term is not there in the standard I think but I am using for clarity). The memory allocated for the object is automatically released when myClass variable goes out of scope.
Other way of allocating memory is to do a new . In that case, you have to take care of releasing the memory by doing delete yourself.
MyClass* p = new MyClass();
p->DoSomething();
delete p;
Remeber the delete part, else there will be memory leak.
I always prefer to use the stack allocated objects whenever possible as I don't have to be bothered about the memory management.
if you want the object on the stack, try this:
MyClass myclass;
myclass.DoSomething();
If you need a pointer to that object:
MyClass* myclassptr = &myclass;
myclassptr->DoSomething();
First I need to say that your code,
MyClass *myclass;
myclass->DoSomething();
will cause an undefined behavior.
Because the pointer "myclass" isn't pointing to any "MyClass" type objects.
Here I have three suggestions for you:-
option 1:- You can simply declare and use a MyClass type object on the stack as below.
MyClass myclass; //allocates memory for the object "myclass", on the stack.
myclass.DoSomething();
option 2:- By using the new operator.
MyClass *myclass = new MyClass();
Three things will hapen here.
i) Allocates memory for the "MyClass" type object on the heap.
ii) Allocates memory for the "MyClass" type pointer "myclass" on the stack.
iii) pointer "myclass" points to the memory address of "MyClass" type object on the heap
Now you can use the pointer to access member functions of the object after dereferencing the pointer by "->"
myclass->DoSomething();
But you should free the memory allocated to "MyClass" type object on the heap, before returning from the scope unless you want it to exists. Otherwise it will cause a memory leak!
delete myclass; // free the memory pointed by the pointer "myclass"
option 3:- you can also do as below.
MyClass myclass; // allocates memory for the "MyClass" type object on the stack.
MyClass *myclassPtr; // allocates memory for the "MyClass" type pointer on the stack.
myclassPtr = &myclass; // "myclassPtr" pointer points to the momory address of myclass object.
Now, pointer and object both are on the stack.
Now you can't return this pointer to the outside of the current scope because both allocated memory of the pointer and the object will be freed while stepping outside the scope.
So as a summary, option 1 and 3 will allocate an object on the stack while only the option 2 will do it on the heap.
if you want to access a method :
1) while using an object of a class:
Myclass myclass;
myclass.DoSomething();
2) while using a pointer to an object of a class:
Myclass *myclass=&abc;
myclass->DoSomething();
If you have defined a method inside your class as static, this is actually possible.
class myClass
{
public:
static void saySomething()
{
std::cout << "This is a static method!" << std::endl;
}
};
And from main, you declare a pointer and try to invoke the static method.
myClass * pmyClass;
pmyClass->saySomething();
/*
Output:
This is a static method!
*/
This works fine because static methods do not belong to a specific instance of the class and they are not allocated as a part of any instance of the class.
Read more on static methods here: http://en.wikipedia.org/wiki/Static_method#Static_methods
Simple solution for cast pointer to object
Online demo
class myClass
{
public:
void sayHello () {
cout << "Hello";
}
};
int main ()
{
myClass* myPointer;
myClass myObject = myClass(* myPointer); // Cast pointer to object
myObject.sayHello();
return 0;
}
Related
Given the following code:
class MyClass
{
public:
char array[10];
};
int main()
{
MyClass *p = new MyClass;
...
}
As far as I understand - new allocates the object on the heap.
But also, the array is allocated on the stack (no new operator).
So, is the array allocated on heap (because the object is at the heap) or on the program stack?
But also, the array is allocated on the stack (no new operator)
No, the array is a member of the object. It's a part of it. If the object is dynamically allocated, then all of its parts are too.
Note I said all of its parts. We can tweak your example:
class MyClass
{
public:
char *p_array;
};
int main()
{
char array[10];
MyClass *p = new MyClass{array};
// Other code
}
Now the object contains a pointer. The pointer, being a member of the object, is dynamically allocated. But the address it holds, is to an object with automatic storage duration (the array).
Now, however, the array is no longer part of the object. That disassociation is what makes the layout you had in mind possible.
What MyClass *p = new MyClass; really means is that you want to allocate sizeof(MyClass) bytes on the heap/free store to store every member of MyClass. The size of a class is based on it's members. array is a member of MyClass and thus because MyClass is allocated on the free store, so is array.
I'm a bit rusty at this. I'm trying to figure out exactly what happens with object declaration, values and references, stack and heap. I know the basics, but am unsure about the following examples:
struct MyObject
{
int foo;
MyObject(int val)
{
foo = val;
}
MyObject()//[EDIT] default constructor
{
}
}
//...
//1)
//this reserves memory on the stack for MyObject0 and initializes foo:
MyObject a = MyObject(1); //[EDIT] fixed from comments
//2)
MyObject* b = new MyObject(2);//This I know reserves memory on the heap,
//returns a pointer to it (and calls constructor).
//There are also other ways like malloc or memset.
//3)
MyObject c = *(new MyObject(3));// So here we instantiate MyObject on the heap,
//return a pointer to it but the pointer is dereferenced outside the parenthesis.
//Is c now a newly created value type copy on the stack?
//And is the original new MyObject(3) now inaccessible in the heap memory (leaked)
//because the pointer to it was never stored?
//4)
// void myFunc( MyObject c){}
myFunc(c); //Am I doing a member-wise assignment from c to a new function-scope
//temporary MyObject reserved somewhere else in memory (in a stack frame?)?
//Or am I somehow passing a reference to c even though c is not a pointer or reference?
//[EDIT] myFunc(c); would pass as a reference if I had void myFunc( MyObject &c){}
Finally, if I have a MyObject[] myObjArr1 = new MyObject[10]() I have 10 uninitialized MyObject structs on the heap, and a pointer of type MyObject Array on the heap as well.
How do I declare a MyObject array, on the stack, where the MyObject structs within the array are also on the stack? Or is that not a thing you do?
Let me re-comment on a more precise way:
1) This creates an a variable on the stack initializing it with the value of the temporary MyObject(1), that is created on the stack as a MyObject calling MyObject::MyObject(1) as constructor. The compiler may eliminate the intermediate steps. You can do it simply as MyObject a(1); Note: the = is not an assignment
2) Creates a MyObject on heap by calling MyObject::MyObject(2) and returns a pointer to it, used initialize the b pointer.
Forget about malloc and memset: they allocate memory, but DON'T
CONSTRUCT objects. The sooner you will forgot them, the better for you
and anybody else.
3) a Myobject is created on the heap and constructed by calling Myobkect::Myobject(3), then The new returned pointer is dereferenced and the resulting value used to initialize c by copy. The on-heap created object is "forgotten" in there. (Memory leak: you have no chance to access it further)
4) The object c is copied in the local parameter c of myFunc (in fact the two c are two distinct objects) that will exist into the stack up to the function exit.
This question already has answers here:
What and where are the stack and heap?
(31 answers)
Closed 8 years ago.
I am learning c++ and would like to know how a program like this is organized in primary-memory. I understand that there are a stack (with stackframes) and a heap. And I know that dynamically allocating something allocates it on the heap. This is done by operators like malloc or new. But I cant see them in this small c++ program.
The program consists of a main-class and a class named MyClass. This class has:
one constructor
one member variable (int)
one member-function
The main-class defines an object to Myclass and as well defines a pointer to this object.
SO - how are all this organized in memory?
#include <iostream>
using namespace std;
class MyClass {
int i;
public:
MyClass(int n) {
i = n;
}
int get_nmbr() {
return this->i;
}
};
int main() {
MyClass myClass(100), *p;
cout << myClass.get_nmbr() << endl;
p = &myClass;
cout << p;
return 0;
}
Let's go through this line by line.
int main() {
A new function starts with this line, and therewith a new scope.
MyClass myClass(100), *p;
Two things happen here. One, a variable myClass is declared within the function's scope, which makes it a local variable and thus it's allocated on the stack. The compiler will emit machine instructions that reserve enough space on the stack (usually by bumping the sp stack pointer register), and then a call to the class constructor executes. The this pointer passed to the constructor is the base of the stack allocation.
The second variable p is just a local pointer, and the compiler (depending on optimizations) may store this value on the local stack or in a register.
cout << myClass.get_nmbr() << endl;
Call the get_nmbr() method of the local myClass instance. Again, the this pointer points to the local stack frame allocation. This function finds the value of instance variable i and returns it to the caller. Note that, because the object is allocated on the stack frame, i lives on the stack frame as well.
p = &myClass;
Store the address of the myClass instance in variable p. This is a stack address.
cout << p;
return 0;
}
Print out the local variable p and return.
All of your code is only concerned with stack allocations. The result of that is that when the function's scope is left/closed at execution time (e.g. the function returns), the object will be automatically "destructed" and its memory freed. If there are pointers like p that you return from that function, you're looking at a dangling pointer, i.e. a pointer that points at an object that's freed and destructed. (The behavior of a memory access through such a dangling pointer is "undefined" as per language standard.)
If you want to allocate an object on the heap, and therefore expand its lifetime beyond the scope wherein it's declared, then you use the new operator in C++. Under the hood, new calls malloc and then calls an appropriate constructor.
You could extend your above example to something like the following:
{
MyClass stackObj(100); // Allocate an instance of MyClass on the function's stack frame
MyClass *heapObj = new MyClass(100); // Allocate an instance of MyClass from the process heap.
printf("stack = %p heap = %p\n", stackObj, heapObj);
// Scope closes, thus call the stackObj destructor, but no need to free stackObj memory as this is done automatically when the containing function returns.
delete heapObj; // Call heapObj destructor and free the heap allocation.
}
Note: You may want to take a look at placement new, and perhaps auto pointers and shared pointers in this context.
First things first. In C++ you should not use malloc.
In this program, all memory used is on the stack. Let's look at them one at a time:
MyClass myClass(100);
myClass is an automatic variable on the stack with a size equal to sizeof(MyClass);. This includes the member i.
MyClass *p;
p is an automatic variable on the stack which points to an instance of MyClass. Since it's not initialized it can point anywhere and should not be used. Its size is equal to sizeof(MyClass*); and it's probably (but not necessarily) placed on the stack immediately after myClass.
cout << myClass.get_nmbr() << endl;
MyClass::get_nmbr() returns a copy of the member i of the myClass instance. This copy is probably optimized away and therefore won't occupy any additional memory. If it did, it would be on the stack. The behavior of ostream& operator<< (int val); is implementation specific.
p = &myClass;
Here p is pointing to a valid MyClass instance, but since the instance already existed, nothing changes in the memory layout.
cout << p;
Outputs the address of myClass. Once again the behavior of operator<< is implementation specific.
This program (kind of) visualizes the layout of the automatic variables.
You have myClass object and pointer p (declared as MyClass *) created on stack. So. within myClass object the data members i also gets created on stack as part of myClass object. The pointer p is stored on stack, but you are not allocating for p, rather you are having p assigned to address of myClass object which is already stored on stack. So, no heap allocation here, at least from the program segment that you posted.
myClass is allocated on the stack. This program doesn't use heap exept maybe for allocating a stdout buffer behind the scenes. When myClass goes out of scope (e.g. when main returns or throws an exception), myClass is destructed and the stack is released, making p invalid.
In modern C++ it is considered safer to use smart pointers, such as the shared_ptr, instead of raw pointers.
To allocate myClass on the heap you could write:
#include <memory>
int main() {
std::shared_ptr<MyClass> p (new MyClass (100)); // Two heap allocations: for reference counter and for MyClass.
auto p2 = std::make_shared<MyClass> (101); // One heap allocation: reference counter and MyClass stored together.
return 0;
}
I've a simply question.
I have been looking for the answer but I might not found the correct tags or words to find the solution...
The question is, as the title says: Do local variables (which have reserved memory) need to be freed? I meant, for example, if I've got the following function:
myClass* myFunction(){
myClass* A = new myClass;
return A;
}
In case of "yes", where Should I call "delete"? both before and after "return" are nonsense...
Am I right?
Don't use new unless you need to.
This avoids new, and so doesn't need deleting
myClass myFunction(){
myClass A;
return A;
}
If you think you need pointers, consider using smart pointers.
If you want the excitement of raw pointers, this function returns a raw pointer to the caller, and they must delete it when they are done.
myClass * myFunction(){
myClass * A = new myClass;
return A;
}
myClass * thing = myFunction();
//stuff, that might throw an exception, so watch it
// smart pointers FTW
delete thing;
Assuming that your type is defined something like this:
class myClass { /* ... */ };
Your example is not proper C++ (unless you have a myClass* conversion constructor, which you probably don't).
You do not have to new an object that sits on automatic memory:
myClass myFunction(){
myClass a;
return a;
}
When newing an object on dynamic memory, you can then put it into a pointer variable in automatic memory:
myClass* myFunction(){
myClass* a = new myClass;
return a;
}
Here, a might leak, if it isn't freed by the caller.
Presumably, unless you're doing some interesting operator overloading, you mean to assign new myClass to a pointer and return the pointer
myClass *myFunction(){
myClass *A = new myClass;
return A;
}
If that is the case, then yes, you will have to delete it at some point. It will be up to the caller of this function to keep the pointer and delete it when appropriate.
Alternatively you can use smartpointers.
Use shared_ptr instead of raw pointers.
std::shared_ptr<myClass> myFunction()
{
std::shared_ptr<myClass> A = std::make_shared<myClass>(constructor parameters, if any);
return A;
}
void f()
{
std::shared_ptr<myClass> A = myFunction();
}
This will emulate Java-style garbage collection.
I have the following code:
void someFunction() {
.......
myClass obj= *(new myClass());
........
delete &obj;
}
I get a runtime error saying invalid pointer.
The code runs fine without the "delete" line.
I know that I need to re-claim memory allocated dynamically by new operator. But I don't know what is going on in this case and how or even do I need to free the memory?
Thanks
If your intent is for the instance to only exist within the scope of this function, then you don't need to use dynamic allocation...
void someFunction() {
.......
myClass obj;
........
}
... in which case the obj constructor is called when it is declared at myClass obj and the destructor is called when the function returns. Otherwise, if it must be dynamic, then this...
void someFunction() {
.......
myClass* obj = new myClass();
........
delete obj;
}
... in which case the constructor is called when you call new myClass() and the destructor is called when you call delete obj -- but, in this case, you need to declare obj to be a pointer to a myClass object so that there's a place to store the return value from the new.
In your example I don't think you can re-claim the memory.
obj is a copy of the anonymous class you create with *(new myClass()). "obj" is allocated on the stack... it is not allocated on the heap (which is where new allocates from).
When you try to delete &obj you are trying to delete the stack memory for the copy that you created.
Try something like
myClass *obj = new myClass(); // memory is allocated from the heap and a pointer returned
myClass copyOfObj = *obj; // memory is allocated on the stack. a *shallow* copy of obj is made
delete obj.
myClass obj= *(new myClass());
That line:
Creates an instance of myClass with automatic storage duration.
Dynamically allocates an instance of myClass.
Dereferences the returned pointer and copies the object to obj. The pointer to the dynamically allocated object is discarded, resulting in a memory leak.
Call delete on a pointer to a local variable with automatic storage duration, which results in undefined behavior. This object was not allocated with new or any variant of new.
Your code should be:
myClass *p = new myClass();
// use p
delete p;
You probably don't need dynamic memory allocation at all, so...
myClass obj; // that's it!
Next, read up on smart pointers.
std::unique_ptr<myClass> p(new myClass());
// no delete! unique_ptr handles it for you when it goes
// out of scope and has the benefit of being exception safe.
Your obj variable has to hold a reference to the dereferenced pointer, so that it later can (rather oddly) delete it:
myClass& obj;
// ^
But you need not define it this way, you can define a pointer to the memory instead:
myClass* obj = new myClass();
and delete it this way:
delete obj;
Or, better yet, you can use memory management tools like std::unique_ptr:
std::unique_ptr<myClass> obj(new myClass);
But there really is no use here for dynamic memory as far as I can see, just intantiate it as a normal variable:
myClass obj;
myClass obj= *(new myClass());
This first creates a myClass object with automatic storage duration named obj. This object is initialised by the expression *(new myClass()). This expression dynamically allocates a myClass object and then dereferences the pointer to that object. So what you end up doing here, is dynamically allocating an object and then copying that into obj.
You've now lost track of the dynamically allocated object. That's not good. Doing delete &obj; will only take the address of the automatic object and attempt to destroy that, but you must only use delete with dynamically allocated objects.
You could change obj to be a reference and it would work:
myClass& obj = *(new myClass());
This makes sure the dynamically allocated object isn't copied. However, this isn't a good idea. It masks the fact that obj refers to an object that must be deleted. Instead, you're better off storing the pointer itself:
myClass* obj = new myClass();
// ...
delete obj;
Or even better, use a smart pointer like std::unique_ptr<myClass>.
Or even betterer, don't even both dynamically allocating it. Just use an automatic object:
myClass obj;
// No need to allocate or delete anything