Can you determine if a string if freeable in C? [duplicate]
If I say:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char *x;
char *y;
int main() {
x = malloc(sizeof("Hello, world!"));
strcpy(x, "Hello world!");
y = "Hello, world";
free(x);
fprintf(stderr, "okay");
free(y);
}
Then, obviously, the program will print "okay" followed by dying because the "pointer being freed was not allocated"—obviously, because the string was a string literal.
I'd like to write a function that does nothing when given string literals, but calls free when given non-string literals. Is that possible, and if so, how?
I don't think the standard has anything for checking whether a pointer was returned by malloc or not (and you're only supposed to pass those to free) so I'd say no, you can't find that out. You'll have to keep track of it yourself.
No. In C, you have to keep track of what you've allocated yourself.
Some malloc
implementations (such as dlmalloc
) provide some extra functionality for inspecting the heap, but you shouldn't rely on those. dlmalloc
has the function dlmalloc_inspect_all
, which will walk the heap and return to you all of the regions of memory that malloc
has allocated, except for memory-mapped chunks. So you could use that to test if a pointer points to a non-memory-mapped allocation, but it's still a bad idea in general.
And on Windows, don't even think about using [IsBadReadPtr
] to test if a pointer points to readable memory or not -- it should really be called CrashProgramRandomly
.
There is no portable way. However, since most implementations allocate heap objects in a different memory region than literal (string) data, it is possible to make an educated guess if a given string pointer falls within either region.
static char x;
bool isStatic(const void *p)
{
const char * cp = (const char *)p;
// Check if the pointer falls within +/-16K of 'x'
if (cp-16*1024 <= &x && &x <= cp+16*1024)
return true;
else
return false;
}
Obviously, this is a bit of a hack. A much better way would be to directly access the .bss
, .data
, and .text
addresses (these are Unix, Win32 is similar) of your executable after it is loaded into memory, and compare your pointers to those regions.
If you know something about the memory map of your program at execution time, then you might be able to do something. A better idea is to do proper memory management, though.
You can write a wrapper for malloc that tracks the addresses of the memory that was allocated. Then in your free function you can see if that memory is on the list.
Aside from that you might be able to play around with the heap but it won't be even remotely portable.
but why not build GC of some sort or use a GC library.
精彩评论