0

On one hand, if I write the following code :

int* fortytwo_pointer () {
  int v = 42;
  return &v;
}

I get a dangling pointer and I can check this by calling printf ("forty two : %d\n", *(fortytwo_pointer()));

On the other hand

int* copy (int *pointer) {
  return pointer;
}
int* fortytwo_pointer () {
  int v = 42;
  return copy (&v);
}

does not produce the same 'Segmentation fault' error.

I would expect it to also be an instance of a dangling pointer because the value v goes out of scope just the same. Is it true ? If so, how to check that the pointer is indeed dangling ?

Edit : This question is more focused on dynamically checking that a pointer is valid, for example if we get a pointer from a call of a library function. I'm more interested in checking if the code could produce invalid pointers.

QGarchery
  • 29
  • 4
  • Is the error only in your compiler/debugger? Because in the first case it would notice but in the second the compiler/debugger doesn't know you're returning the dangling pointer. – Roy Avidan Dec 17 '19 at 19:25
  • 3
    Dereferencing a dangling pointer may "work" (in quotes), but it's not guaranteed. It's undefined behavior and you should not rely on it. – jweyrich Dec 17 '19 at 19:25
  • 6
    "can check this by calling printf". No you can't. It's not guaranteed to seg fault and in fact in many cases it may not. That's what is referred to as "undefined behvaiour" in C. Unfortunately the language doesn't have any easy way to check whether a pointer is valid before accessing it. There are some platform specific ways. But in general C programmers need to rely on development best practices such as code reviews, testing and debugging to root out memory issues like this. There are also tools such as [valgrind](http://valgrind.org) which can help. – kaylum Dec 17 '19 at 19:34
  • 2
    *...I can check this by calling `printf ("forty two : %d\n", *(fortytwo_pointer()));`* Not really. It's undefined behavior. *On the other hand... does not produce the same 'Segmentation fault' error.* Because it's undefined behavior. – lurker Dec 17 '19 at 19:36
  • Does this answer your question? [Testing pointers for validity (C/C++)](https://stackoverflow.com/questions/551069/testing-pointers-for-validity-c-c) – kaylum Dec 17 '19 at 19:36
  • regarding: `int v = 42; return &v;` this is returning the address of a variable that is located on the local stack of the function. When that function exits, that variable goes out-of-scope. It is an error to return the address of a variable that is on the local stack. – user3629249 Dec 18 '19 at 04:26
  • Thank you all for your feedback! In the first case I get a warning from the compiler 'function returns address of local variable' and the 'Segmentation fault (core dumped)' when I execute the program. In the second case I get no warning and the program prints 'forty two : 42'. I edited my question to explain the difference with the question 'testing pointers for validity'. – QGarchery Dec 18 '19 at 10:22

2 Answers2

3

Yes, you do. As pointed out in the comments on your question, you cannot "check it" by using printf. From the moment that the function stack is popped, you're dealing with undefined behavior.

Use valgrind to run your program, and it will point out any read/write errors. Those may not cause your program to fail every time, but should be taken care of nonetheless. I'm sure your dangling pointer will show up in there, and valgrind will be kind enough to show you the full trace of where each error occurs.

Saucy Goat
  • 1,587
  • 1
  • 11
  • 32
0

I would expect it to also be an instance of a dangling pointer because the value v goes out of scope just the same. Is it true ? If so, how to check that the pointer is indeed dangling ?

Yes, the variable you have declared in int* fortytwo_pointer() is a local variable. This means the variable you have declared stores in a stack frame and at the end of this function, the variable is going to become freed and there's no a good address to dereference and that's why v is a dangling pointer.

My suggestion to resolve this problem is allocating memory from heap by using some functions such as malloc() or calloc(). Functions delete all variables in stack, not heap.

So, you can write your code below :

int* fortytwo_pointer () {
int *v = (int*) malloc (sizeof(int));
if(v == NULL)
{
    printf("An error occurred.\n");
    getch();
}

*v = 42;
return v;
}

and finally, don't forget to free *v pointer. You can free that by using free().