8
struct node
{
  Item item; node *l, *r;
  node(Item x) {item = x; l = 0; r = 0;}
};

typedef node* link;
link max(Item a[], int l, int r)
{
    int m = (l+r)/2;
    link x = new node(a[m]);
    if (l==r) return x; // return a local pointer
    x->l = max(a, l, m);
    x-r = max(a, m+1, r);
    Item u = x->l->item, v = x->r->item;
    if (u>v) x->item = u;
    else x->item=v;

    return x;    // return a local pointer
}

This is a piece of code from "Algorithm in c++" by Robert Sedgewick, page 252, Program 5.19. And in function max(), the returned variable is a pointer which is created inside the function.

In my opinion, returning a local pointer is not allowed in c/c++. So my question is that "is that OK to write a function like this"? I cannot believe such a classic book make mistake like this. Or I misunderstood the principle? Please help. Thanks.

Mysticial
  • 464,885
  • 45
  • 335
  • 332
Ke Li
  • 157
  • 4
  • 9
  • `link x = new node(a[m]);` != local pointer – Mysticial Mar 20 '12 at 00:09
  • 1
    @Mysticial: Pedantically speaking, it *is* a local pointer, but it doesn't point to a local object :-) – Kerrek SB Mar 20 '12 at 00:12
  • In `c` returning a pointer to a local variable with result in a warning, and probably should be avoided unless you know what you're doing, but it will work. Not sure is `c++` changes that into an error. – twain249 Mar 20 '12 at 00:15
  • 1
    @twain249: It's not an error in C++. Are you saying that the C standard mandates a diagnostic? Do you have a reference for that? – Kerrek SB Mar 20 '12 at 00:16
  • @KerrekSB I just made a function like this `int *fun() { int a = 3; return &a;}` and compiled it, using gcc, to see what would happen and I got a warning. So I guess all I can say for sure is that gcc causes a warning for this. – twain249 Mar 20 '12 at 00:18
  • 1
    @twain249: That's all very edifying, but I don't think that "proof-by-that's-what-my-compiler-does" will pass for a statement about the C standard :-) – Kerrek SB Mar 20 '12 at 00:20
  • @KerrekSB I agree it's not a proof about the C standard that's why I qualified it in my second comment. – twain249 Mar 20 '12 at 00:22

3 Answers3

5

x isn't a "local pointer" - that is, a pointer to a local variable. *x was allocated using new. x points to dynamically allocated memory and returning that pointer is just fine. So yes, it's OK to write a function like this one, and there's not an error in the book.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
Carl Norum
  • 219,201
  • 40
  • 422
  • 469
4

It is an error to return a pointer to a local variable. x points to a variable allocated on the heap:

link x = new node(a[m]);

Thus x isn't pointing to a local variable.

The reason that returning a pointer to a local variable is an error is that such a variable exists for only as long as the function is active (i.e. between it is entered and exited). Variables allocated on the heap (e.g. with the use of the new operator) exist until they are deallocated (e.g. with the delete operator).

Adam Zalcman
  • 26,643
  • 4
  • 71
  • 92
  • 1
    So the memory allocated to x will not be freed until we explicitly do so. Or can I say memory allocated on function stack will be undefined if the variable goes out of scope; but on heap will not? – Ke Li Mar 20 '12 at 00:22
  • 1
    Yes. You do need explicit deallocation. Also, a variable allocated on the heap will continue to exist after returning from the function which allocated it. – Adam Zalcman Mar 20 '12 at 00:29
1

This is perfectly fine, because the contents of x are allocated on the heap, not the stack. You might be getting confused since there is a typedef node* link; in there, making it look like a stack allocation since it masks the fact that x is actually a node *.

jli
  • 6,523
  • 2
  • 29
  • 37
  • 1
    `x` is an automatic variable. You were maybe thinking about `*x`. – Kerrek SB Mar 20 '12 at 00:13
  • @KerrekSB yeah I suppose I meant "the contents of `x` are allocated on the heap", edited for clarity. – jli Mar 20 '12 at 00:15
  • Actually, the contents of `x` are the contents of an automatic variable. You were maybe thinking about the contents of `*x`? – Kerrek SB Mar 20 '12 at 00:15
  • @KerrekSB I guess we have differing definitions of "the contents", and I guess yours is probably the more correct one. – jli Mar 20 '12 at 00:17