C Assign Pointer to NULL

Your statement a=NULL in my_function() indeed sets the value of a to NULL, but a is a local variable of that function.When you passed ptr to my_function() in main(), the value of ptr was copied to a.I suppose your whole confusion arose from the * used before a in the definition of my_function().

Pointers are generally passed to functions when we want to manipulate the original values which those pointers point to, from the called function, and this is done by dereferencing those pointers from the called functions.In this case, had you used this:

*a= blah blah;

it would have reflected in the value at the address pointed to by ptr in main().But since you want to change the value of ptr itself, you need to be able to have a way to manipulate it from my_function().For this you use a pointer-to-pointer,ie of type char**.You pass such a char** as argument to my_function(() and use it to alter the value of ptr.Here's the variation to your code that would do it for you:

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

void my_function(char **); // Change char* to char**

int main(int argc, char *argv[]) {
    char *ptr;
    ptr = malloc(10);

    if(ptr != NULL) printf("FIRST TEST: ptr is not null\n");
    else printf("FIRST TEST: ptr is null\n");

    my_function(&ptr); //You pass a char**

    if(ptr != NULL) printf("SECOND TEST: ptr is not null\n");
    else printf("SECOND TEST: ptr is null\n");
}

void my_function(char **a) {  //Change char* to char** here
    *a = NULL;
}

It's because the pointer is passed by value and not by reference. If you want to change the pointer inside the function you need to pass the actual pointer as a pointer, i.e. a pointer to a pointer:

void my_function(char **a)
{
    *a = NULL;
}

Use the address-of operator & when you call the function to get the address of the pointer:

my_function(&ptr);