2

The following application works with both the commented out malloced int and when just using an int pointer to point to the local int 'a.' My question is if this is safe to do without malloc because I would think that int 'a' goes out of scope when function 'doit' returns, leaving int *p pointing at nothing. Is the program not seg faulting due to its simplicity or is this perfectly ok?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef struct ht {
    void *data;
} ht_t;

ht_t * the_t;

void doit(int v)
{
    int a = v;
    //int *p = (int *) malloc (sizeof(int));
    //*p = a;
    int *p = &a;

    the_t->data = (void *)p;
}

int main (int argc, char *argv[])
{
    the_t = (ht_t *) malloc (sizeof(ht_t));
    doit(8);
    printf("%d\n", *(int*)the_t->data);
    doit(4);
    printf("%d\n", *(int*)the_t->data);
}
glglgl
  • 89,107
  • 13
  • 149
  • 217
user740521
  • 1,175
  • 4
  • 12
  • 25

5 Answers5

5

Yes, dereferencing a pointer to a local stack variable after the function is no longer in scope is undefined behavior. You just happen to be unlucky enough that the memory hasn't been overwritten, released back to the OS or turned into a function pointer to a demons-in-nose factory before you try to access it again.

IllusiveBrian
  • 3,105
  • 2
  • 14
  • 17
3

Not every UB (undefined behaviour) results in a segfault.

Normally, the stack's memory won't be released back to the OS (but it might!) so that accessing that memory works. But at the next (bigger) function call, the memory where the pointer points to might be overwritten, so your data you felt like bing safe there is lost.

glglgl
  • 89,107
  • 13
  • 149
  • 217
1

malloc() inside a function call will work because it stores on heap. The pointer remains until you free the memory.

And yes, not every undefined behaviour will result in segmentation fault.

Vamsi
  • 878
  • 1
  • 8
  • 25
0

It does not matter that p does not point at anything on return from doit.
Because, you know, p isn't there any more either.

It does matter that you are reading the pointer to a no-longer-existing object in main though. That's UB, but harmless on most modern platforms.
Even worse though, you are reading the non-existent object it once pointed to, which is straight Undefined Behavior.

Still, nobody is obliged to catch you:
Can a local variable's memory be accessed outside its scope?

As an aside, Don't cast the result of malloc (and friends).
Also, be aware that not free-ing memory is not harmless on all platforms: Can I avoid releasing allocated memory in C with modern OSes?

Community
  • 1
  • 1
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
0

Yes, the malloc is needed, otherwise the pointer would point on the 4-byte space of the stack, which would be used by other data, if you called other functions or created now local variables.

You can see that if you call that function afterwards with a value of 10:

void use_memory(int i)
{
    int f[128]={};
    if(i>0)
    {
        use_memory(i-1);
    }
}
benaryorg
  • 915
  • 1
  • 8
  • 21