-2

I understand that atexit() takes in a function pointer of this type void (*function)(void). What I want to do is that whenever the porgam exists it runs a function to free of all the memory. So I want atexit() to take in this function pointer instead void (*function)(struct Node). Is there a way around this, or something similar that will allow me to do this.

carlosdafield
  • 1,479
  • 5
  • 16
  • 2
    When `exit()` is calling the function, how would it know what to pass as the `struct Node` argument? – Barmar Nov 22 '21 at 22:16
  • 1
    the callback functions can't take arguments. If they need to process any data, it must be global variables. – Barmar Nov 22 '21 at 22:17

2 Answers2

4

You could add your own register for cleanup functions:

typedef void atexit_f(void*);
void my_atexit(atexit_f* callback, void *data);

The register would be kept in a global variable (i.e. linked list). The register would be cleaned up in a cleanup function registered with atexit().

struct cleanup_node {
   atexit_f *cb;
   void *data;
   struct cleanup_node *next;
};

static struct cleanup_node *head;

void my_atexit_cleanup(void) {
  for (struct cleanup_node *node = head; node; node = node->next) {
     node->cb(node->data);
  }
  // free nodes itself
}

...

int main() {
  atexit(my_atexit_cleanup);
  ...
  my_atexit(some_function, some_data);
}
tstanisl
  • 13,520
  • 2
  • 25
  • 40
3

The function you pass to atexit must have a matching function signature.

If this function's job is to free some memory, the pointer to that memory must be made available as a file-scope variable.

dbush
  • 205,898
  • 23
  • 218
  • 273