0

Suppose I have 2 pointers to the same object.

int * a = malloc(sizeof(int));
*a = 5;
int * b = a;
free(a);
a = NULL;

At this point I know that a == NULL but b is still pointing to that address that has been freed. Is it possible to know through b that the memory has been freed?

The scenario is that I am running unit tests and I want to make sure that some structs are freed at the right time under the right conditions and so I would like to avoid having to add infrastructure just to support testing.

eftshift0
  • 26,375
  • 3
  • 36
  • 60
  • 1
    Not that I'm aware of. What's your motivation for doing this? You could create a structure to contain this and add a `has_been_freed` flag. – ggorlen Aug 12 '20 at 01:38
  • @ggorlen I will add a little more info so you can see why I won't add more infrastructure. – eftshift0 Aug 12 '20 at 01:46

1 Answers1

3

Short answer: no. Long answer: definitely not :-)

There are tricks you can implement, such as the use of doubly-indirect pointers (an allocated structure that contains the pointer to the actual back-end data)(a), this is basically how smart pointers work in C++ and I've seen them implemented in C before(b). These are much more complex than raw pointers in that they may require mutex-protected reference counts, and all usage to only go through the API.

But the code manipulating these pointers may not necessarily be your code so, if you pass the back-end pointer through to some function that frees it without going through your API, all bets are off. In addition, it adds an extra level of indirection expense to every access.


(a) A simple example of this (no reference counting) is along the lines of:

pointerA      +---------------+    +-------------+
        >---> | smart pointer | -> | actual data |
pointerB      +---------------+    +-------------+

All access is indirect via the smart pointer, which can be set to NULL when either of pointerA or pointerB is "freed". Hence, if you free pointerA, then try to use pointerB, the value you get will be NULL.

This requires an API for creating and destroying the smart pointers, getting and setting the back-end raw pointer, and so on.


(b) GObject, for example, is a partially reference-counted variant using smart pointers in C. It forms the basis of the object model in Gtk and GStreamer.

Early versions of Windows, long before protected mode when there was no memory management hardware (I'm revealing my age there !) used a similar double-indirect scheme so it could move memory around at will without all the processes ending up with invalid pointers.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953