4

From the thread in

When should I use the new keyword in C++?

The answer talks about when "new" must be used in order to create a pointer to an object if you need to return the pointer to the object from the function.

However, my code below works fine. I use a local pointer instead of allocating some memory to a new pointer.

node* queue::dequeue(){
  if(head==0){
    cout<<"error: the queue is empty, can't dequeue.\n";
    return 0;
  }
  else if(head->next !=0){
    node *tmp=head;
    head=head->next;
    tmp->next=0;
    return tmp;
  }
  else if(head->next ==0){
    node *tmp=head;
    head=0;
    tmp->next=0;
    return tmp;
  }
}

It is a simple dequeue() operation. My tmp is a local pointer. But i still return it.

Credit to Mahesh

I have following statements in the main()

node a8(8); //node constructor with the value

Therefore tmp points to what head points to, and head points to different nodes like a8.

Since a8 is valid throughout the main(), tmp is valid throughout the main() as well

Community
  • 1
  • 1
WriteBackCMO
  • 629
  • 2
  • 9
  • 18
  • You did allocate the memory on the heap - you just did it outside of `dequeue`. You likely have another member, say `enqueue`, that created all those nodes and strung them together. That thread you cite doesn't talk about memory for a pointer, but memory for the object that pointer points to. – Igor Tandetnik Sep 10 '13 at 04:20
  • 1
    Returning the value of a local pointer is not a problem. Returning a pointer to a local object is a problem, and you're not doing that. – Keith Thompson Sep 10 '13 at 04:22

3 Answers3

7

Program works fine because the memory location pointed by tmp lifetime is beyond the scope the dequeue member function. tmp lies on stack and it's life time end as the function returns but it is not the case with the memory location it was pointing to.

By contrast, this code is not safe:

int* boom()
{
    int sVar = 10;
    int *ptr = &sVar;

    return ptr;
} // life time of sVar ends here

The memory location ptr points to is valid until the function returns (but not after it returns).

Mahesh
  • 34,573
  • 20
  • 89
  • 115
  • Can I understand in this way: head is assigned to tmp, therefore whatever tmp points to is what head points to. Because head exists in the main() and therefore, tmp is valid inside main() as well. – WriteBackCMO Sep 10 '13 at 04:34
  • You have to think in terms of variable scope. When it's life time starts and ends. `tmp` by itself is not valid but the memory location it was pointing to is valid after the function returns. Life time of `tmp` is different from the lifetime what it is pointing to in this case. – Mahesh Sep 10 '13 at 04:36
1

The function returns a local pointer which is a copy of a global (or class member) pointer, head. It is not returning a pointer to a local variable. It is OK.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
0

I am providing my opinion only for discussion. I have used the following code for returning objects passed in from outside with the knowledge that the object can be destroyed by this function. The passed in object could be created locally. Usually there are some logic to return a new object or using existing object for efficiency purpose. Working with memory is always very tricky sometimes (can take a few days or longer to fix the bug).

Objx* funcAvoidNew(Objx& obj) {
  if (somecondition) {
    return new Objx();
  else {
    Objx* p = new Objx;
    *p = std::move(obj);
    return p;
}
Kemin Zhou
  • 6,264
  • 2
  • 48
  • 56