Is there a way to determine if free () can fail?

Is there a way to determine if free() can fail if it is ever called on a specific pointer to a block of memory?

I have the following situation: a thread that has access to a shared resource fails while it can be in the release state of the specified resource. Now I need to develop a safe way to clean this share.

Of course, I assigned a resource for the usual case, but what about the above limit?

UPDATED: If I use additional synchronization mechanisms, this only does a lot of cleaning, and may include additional restrictions. I would like to limit / avoid if possible.

Permission . I finally decided to re-factor. Thanks to all the participants. You guys rock!

+2
source share
4 answers

I have seen all kinds of attempts, including this one:

 void m_free(void **p) { if (*p != NULL) { free(*p); *p = NULL; } } 

Deploying dereferencing like interrupt not only breaks down various platforms, โ€œincluding this example inโ€ can only work if you initialize, free and reinitialize every single pointer in every existing function (compiled libraries are included) and work with C, which does the same thing .

Then apply optimization and blocking of safe flows. Bang!

In short, if you canโ€™t keep track of what you have allocated in one function, it is time to change this function. Do it enough ... and you will find that the need for secure free () goes away quickly. Valgrind is your friend if you work on a supported platform. According to your tags, this is really your friend :)

Or use malloc (), which collects garbage at its own expense, depending on how you distribute things and get rid of free () at all. After that, debugging becomes almost infinitely interesting.

Hopefully you are rebuilt? Although you seem to have a problem (also) with mutual exclusion, it just leads to re-factorization. Ie, let the line before free () block or fail when trying to get a lock .. and set the free pointers to NULL in the thread with the lock, at least in the structures you implement.

+6
source

I do not believe that there is an appropriate interface that does what you want.

I can come up with a few tricks. You might have an error-triggered thread that calls a wrapper around free() instead of free() directly; the shell can save the address or the last few addresses so that you can determine if the block has been released. You can also block signals, set a critical section, or do something else that can interrupt the stream *.

Update: Does a dying thread ever free up this memory before exiting / clearing? I often write malloc front-end (as a speed optimization) for a memory that does not need to be freed in a stationary state. If the stream is simply configurable, you can split the memory before starting the stream and invoke the stream for an interface that simply outputs the unrelated, unrealizable parts of the dynamic block. It will work faster, and then when the thread dies, you can immediately free the entire block. The main idea here is for a thread that is prone to crash to get its memory by calling a service that can clear after the fact.

Another idea: what about heaps in the stream? If the threads could be persuaded to allocate the memory necessary only during their lifetime from their own heap, which would organize the cleanup task well to free the entire heap of threads when the thread joins the parent object.

+2
source

I think there is no way to do what you ask.

The problem is that there is no way to determine what state the dying stream was in when it died. Did it just call free () and move on? Failed () to add the block back to the free list? You can not say.


If this is really a rare condition for the thread to die this way (and therefore you can leave some free memory around - you just want to know not to use it), then the following (using Windows calls) frees up memory and "marks" it as free for your other threads:

 void* ptr; ... void* desiredPtr = ptr; if(InterlockedCompareExchangePointer(&ptr, NULL, desiredPtr) == desiredPtr) free(desiredPtr); 

What he does is that ONLY one thread tries to free memory and before he sets the address to NULL so that no other thread tries to free it.


If this is unacceptable for the memory to be locked around, the best way would be to have a separate thread whose only job is to free the memory. Other threads can then place free requests on the free memory stream. Since the free memory stream is so simple, it does not have to die and can normally complete the job.

+1
source

If you call free with a valid pointer, I don't see how this happens. If it does not work, this must be due to an invalid pointer.

In addition to synchronizing access to shared memory (such as mutex ), it should be clear that to avoid cases such as double-freeing. Double freeing is when two or more threads have a valid pointer, but then more than one thread is trying to free memory. Although the second thread has a non-zero pointer, it is no longer valid.

If you are worried about memory issues in C / C ++, you can try a memory library like HeapAgent . A memory library like this will be a tool and initialize the distribution of each memory. Before freeing up memory, it checks to see if the memory pointer is valid and there were no buffer overflow errors. There should not be any code changes, as it can simply replace the built-in malloc / free. In addition, the library can help find memory leaks, overwrite and invalid links.

Another strategy to solve your problem may be to centralize the cleaning of resources in one thread. When a thread runs on a resource, it simply notes that it is available for cleaning using the garbage collector.

Of course, then there is Plan C - use Java ... Just kidding.

0
source

All Articles