Allora direi che se vuoi essere portabile non devi dipendere da macro del compilatore e da calcoli strani sugli indirizzi. Io vedrei due soluzioni:
- passare un parametro che specifica se il puntatore e' sull'heap o no;
- definirti una tua gestione del'heap e passare istanze di questa memoria, esempio:
codice:
void *myAlloc(size_t sz)
{
  char *r = malloc(2 + sz);
  *r = 0x4E;
  *(r + 1) = 0xE4;
  return r + 2;
}

void myFree(void *ptr)
{
  char *r = (char *)ptr;
  r -= 2;
  if( (*r == 0x4E) && (*(r + 1) == 0xE4 )
  { // Allocata con myAlloc.
    free(r);
  }
  else
  { // Sullo stack o allocata con malloc.
  }
}
Poi richiedi di usare la tua myAlloc/myFree invece che la malloc/free. Se poi quello usa ancora malloc e free fatti suoi.
A questo punto:
codice:
void mia_funzione (void *mio_punt) {
       if (mio_punt == NULL) {
              mio_punt = myAlloc();
       } else {
       }

       /* ============================== */
       myFree(mio_punt);
       /* ============================== */
}
Al solito il codice non l'ho provato...e' solo una idea. Sinceramente io cambierei la funzione o meglio ristrutturerei il codice in C++ che mi darebbe più strumenti per far si che il mio codice venga usato in modo certo e come voglio io