0

This code is taken from: page 20-21 of this lecture notes pdf from ocw.

 struct node∗ nalloc ( int data )
 { 
    struct node∗ p=( struct node ∗) malloc ( sizeof (node )) ; 
    if ( p!=NULL) {
        p−>data=data ;
        p−>next=NULL;
    }
    return p;
 }

struct node∗ addfront ( struct node∗ head , int data )
{ 
    struct node∗ p= nalloc (data ); 
    if ( p==NULL) return head ;
    p−>next=head;
    return p;
}

I think the code is wrong because the pointer p is local to nalloc() and using it in addfront() would yield undefined behavior. I have seen the answer to this question and believe I am correct but can someone verify?

selbie
  • 100,020
  • 15
  • 103
  • 173
Archer
  • 271
  • 5
  • 15
  • 2
    the pointer `p` in both functions refers to dynamically allocated memory. When you return from a function the **stack** gets destroyed. Dynamically allocated memory is on the **heap** and is valid even at the end of the function. So, this code is correct. – Rishikesh Raje Jan 20 '20 at 08:41
  • `p` is local and it will be destroyed once the program flow gets out of the function `nalloc` but the memory it allocated will exist even after nalloc (until `free`d) and the address of the memory (if) allocated in `nalloc` by `p` is valid. – Agrudge Amicus Jan 20 '20 at 08:41
  • Your code looks correct to me. – selbie Jan 20 '20 at 08:47
  • Quibble. There is no need to cast the return of `malloc`, it is unnecessary. See: [Do I cast the result of malloc?](http://stackoverflow.com/q/605845/995714) – David C. Rankin Jan 20 '20 at 08:52
  • @DavidC.Rankin For the missing header case, compiler issues a warning: `include '' or provide a declaration of 'malloc'` – Agrudge Amicus Jan 20 '20 at 09:07
  • What is it with so many people casting malloc? – anastaciu Jan 20 '20 at 09:11
  • @anastaciu So the code can be compiled with a C++ compiler too. – Aykhan Hagverdili Jan 20 '20 at 09:12
  • @Ayxan, I see, though the reason for that still puzles me. – anastaciu Jan 20 '20 at 09:39
  • @AgrudgeAmicus - the compiler will provide an implicit declaration of `mailloc`, but the implicit declaration will not be compatible with normal `malloc` (the implicit implementation will return type `int` -- the default in C) – David C. Rankin Jan 20 '20 at 21:59

2 Answers2

1

The function is right. But your logic is not so wrong. The variable p is effectively local and won't exist anymore when the function will return. However, p is not the memory you allocated with malloc, but a variable storing the address of the memory you allocated.

Thus, the statement return p; will return a copy of p, so a copy of the address of the memory you allocated using malloc().

In the linked question, the user creates a local array and returns a pointer to it. See, the array is local and now dynamically allocated using new or malloc(). So his variable effectively contains the (automatically) allocated memory, and not the address of it. However, only the address is returned so the memory is lost.

Quentin
  • 724
  • 7
  • 16
0

You are not correct. While p is a local variable on stack, what it points to isn't. What is happening is a pointer to a node on the heap is returned from nalloc and a copy of that pointer is used safely in addfront. The code is fine.

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
  • How is it different from the msg pointer in the linked question? – Archer Jan 20 '20 at 09:06
  • @Archer `msg` is s *static* array on the stack. It is destroyed when the function returns. `p` is pointing to *dynamically allocated* memory, which is fine to use until it is freed with `free()`. – Aykhan Hagverdili Jan 20 '20 at 09:08