37

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.

Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
  • 3
    Objects are not normally heap allocated. Only dynamically allocated objects (i.e. those allocated with the `new` keyword) are on the heap. Local variables, as well as pointers (not the objects they point to) are located on the stack. – Dunya Degirmenci Jun 07 '10 at 09:27

7 Answers7

57

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.

  • Good answer, although shouldn't line three read `myclass = ...`? As it is now you are dereferencing an invalid pointer and giving it the address of c, or am I just in dire need of caffeine? – Skurmedel Jun 07 '10 at 09:27
  • what happens if u do `delete myclass` can you delete objects of stack allocated? – cs guy Jan 23 '21 at 22:08
29

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.

Naveen
  • 74,600
  • 47
  • 176
  • 233
12

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();
Johan Kotlinski
  • 25,185
  • 9
  • 78
  • 101
2

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.

Community
  • 1
  • 1
Malith
  • 381
  • 6
  • 18
1

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();
Steve H.
  • 6,912
  • 2
  • 30
  • 49
harsha217
  • 72
  • 1
  • 11
1

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

-1

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;
}
Ali Soltani
  • 9,589
  • 5
  • 30
  • 55