views:

39

answers:

3

Let's say I have an allocation in memory containing a string, "ABCDEFG", but I only have a pointer to the 'E'. Is it possible, on win32, to free that block, given a pointer that is within the block, but not at the start? Any allocation method would work, but a Heap* function would be the path of least resistance.

If not a native solution, have there been any custom memory managers written which offer this feature?

EDIT: This isn't an excuse to be sloppy. I'm developing an automatic memory management system using 100% compile-time metadata. This odd requirement seems to be the only thing standing in the way of getting it working, and even then it's needed only for data types based on arrays (which are slicable).

+1  A: 

I suppose if you know what the malloc() guard blocks look like, you could write a function that backs up from the pointer you pass it until it finds a 'best guess' of the original memory address and then calls free(). Why not just keep a copy of the base pointer around?

Carl Norum
Scanning back to the guard block would be a bad idea because of (a) the performance of a sequential scan and (b) it's nearly impossible to be sure the pattern you've found in memory is indeed a guard block. We probably agree that keeping track of start addresses of block allocations is the only sensible solution.
Carl Smotricz
+1  A: 

If you use VirtualAlloc to allocate memory, you can use VirtualQuery to figure out which block a pointer belongs to. Once you have the base address, you can pass this to VirtualFree to free the entire block.

casablanca
This looks great, except for the page-granular allocations. My memory requirements would balloon like there's no tomorrow and no 32-bit address limit.
zildjohn01
+3  A: 

It would be possible for the memory allocation routines in the runtime library to check a given memory address against the beginning and end of every allocated block. That search accomplished, it would be easy to release the block from the beginning.

Even with clever algorithms behind it, this would incur some kind of search with each memory deallocation. And why? Just to support erroneous programs too stupid to keep track of the beginning of the blocks of memory they allocated?

The standard C idiom thrives on treating blocks of allocated memory like arrays. The pointer returned from *alloc is a pointer to the beginning of an array, and the pointer can be used with subscripts to access any element of that array, subscripts starting at 0. This has worked well enough for 40 years that I can't think of a sensible reason to introduce a change here.

Carl Smotricz
+1 - "And why? Just to support erroneous programs too stupid to keep track of the beginning of the blocks of memory they allocated?"
SB
I'm willing to accept some runtime penalty... I suspect it could minimized fairly easily anyways (think: binary search). Remember that all dynamic allocation is nondeterministic to being with. And just because something's been done the same way for 40 years is no reason not to innovate, in fact I'd say the opposite is true. See my edit.
zildjohn01
Well, if you're writing the memory management system, you're in a perfect position to address the problem. You'll want to keep a balanced b-tree of starting addresses chunks of memory you allocate, and when you want to release a chunk of memory given a pointer to somewhere inside it, you search your tree for the highest starting address lower than your pointer. Apart from the effort of housekeeping the tree, that solves your problem. Search times will be O(logN) in the number of allocated chunks.
Carl Smotricz
Assuming I layer on top of an existing allocator, that actually sounds pretty straightforward. Have a +1 although I'm going to hold out for an answer in case somebody knows a library that's built for this kind of usage.
zildjohn01