Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reassigning null pointers

Can a null pointer be reused? If yes, under what conditions?

More specifically, can anyone tell what happens with this piece of code?

int *p = 0;
p = (int*)malloc(sizeof(int));

If it's problematic - why? And what is the correct way to do it?

EDIT: I know it's not necessary to do it like that. I'm asking what happens in order to understand the way pointers work in C.

like image 536
Lior Kotlar Avatar asked Jun 15 '26 00:06

Lior Kotlar


2 Answers

Can a null pointer be re-used?

Yes

if yes, under what conditions?

Always

Your question is actually equivalent to ask when it's ok to reuse an int that has been set to zero, or any other value for that matter. What you need to know is that you cannot undo an assignment, so whatever value the pointer contains will be lost. This is the only direct consequence of reassigning a pointer, null or not null. Any problems will be a consequence of no longer having access the previous value. The reassignment itself is always fine, provided it's done properly. See below.

There are basically two common problems related to this when it comes to pointers.

  1. Dangling pointers. This will happen after you call free on a pointer. It will also happen if the object the pointer is pointing at goes out of scope. A dangling pointer contains garbage, and it's undefined behavior to dereference it.

  2. Memory leaks. If you have allocated memory with malloc or similar to a pointer p and then reassign the pointer, you may lose the ability to free the allocated memory.

But it is always legal to reassign a pointer. What value it contains does not affect that. Consider this code:

...
int *p;
...
p = x;

If this is ok or not will entirely depend on x. Both it's type and value and if it is initialized or not.

More specifically, can anyone tell what happens with this piece of code?

It does work. But I have a few remarks.

  1. It's not necessary to initialize the pointer to null before assigning. Some say it's a good habit. Others say it's bad. There are pros and cons and depends on the situation. I personally think it's bad1 to always2 use it.
    1 In short, my argument is that if null initialization solves a problem, then you might have a much bigger problem in your design that the initialization will not solve, but only hide.
    2 There are valid use cases. Use it in those cases, but make sure you understand why you're doing it.

  2. There's no need to cast the result from malloc. Again, some say it's good. Some say it's bad. I think it's bad, unless you want to compile the C code with a C++ compiler.

  3. Don't use sizeof(int). Use sizeof *p instead.

See Do I cast the result of malloc? to read about 2 and 3.

I'd write your code as

int *p = malloc(sizeof *p);
if(!p) {
    // Handle error
}
like image 51
klutt Avatar answered Jun 16 '26 12:06

klutt


This declaration

int *p = 0;

declares the variable p that is initialized by a null pointer constant.

As any other variable that is not qualified the variable p can be reassigned with a new value as for example

p = (int*)malloc(sizeof(int));

Note: in C you can also just write

p = malloc( sizeof( int ) );

You could not reassigned the variable if it was declared with the qualifier const like

int * const p = 0;

Here is a simple demonstration program

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

int main( void )
{
    int *p = 0;

    p = malloc( sizeof( int ) );

    if ( p != NULL )
    {
        *p = 10;
        printf( "*p = %d\n", *p );
    }

    free( p );

    int x = 20;

    p = &x;

    printf( "*p = %d\n", *p );
}

Pay attention to that you may call the function free for a null pointer.

like image 44
Vlad from Moscow Avatar answered Jun 16 '26 12:06

Vlad from Moscow



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!