does free always (portably) frees & reserve memory for the process or returns to the OS
I have read that free() "generally" does not return memory to the OS. Can we portably make use of this feature of free(). For example,is this portable?
/* Assume I know i would need memory equivalent to 10000 integers at max
during the lifetime of the process */
unsigned int* p = malloc(sizeof(unsigned int) * 10000);
if ( p == NULL)
return 1;
free(p);
/* Different points in the program */
unsigned int* q = malloc(sizeof(unsigned int) * 5);
/* No need to check for the return value of malloc */
I am writing a demo where I would know in advance how many call contexts
t开发者_Python百科o support.
Is it feasible to allocate "n"
number of "call contexts" structures
in advance and then free
them immediately. Would that guarantee that my future malloc
calls would not fail?
Does this give me any advantage with regards to efficiency? I am thinking one less "if" check plus would memory management work better if a large chunk was initially acquired and is now available with free. Would this cause less fragmentation?
You would be better off keeping the initial block of memory allocated then using a pool to make it available to clients in your application. It isn't good form to rely on esoteric behaviors to maintain the stability of your code. If anything changes, you could be dealing with bad pointers and having program crashes.
You are asking for a portable and low level way to control what happens on the OS side of the memory interface.
On any OS (because c is one of the most widely ported languages out there).
Think about that and keep in mind that OSs differ in their construction and goals and have widely varying sets of needs and properties.
There is a reason the usual c APIs only define how things should look and behave from the c side of the interface, and not how things should be on the OS side.
No, you can't reliably do such a thing. It is portable only in the sense that it's valid C and will probably compile anywhere you try it, but it is still incorrect to rely on this supposed (and undocumented) behaviour.
You will also not get any appreciably better performance. A simple check for
NULL
returns frommalloc()
is not what's making your program slow. If you think all your calls tomalloc()
andfree()
are slowing your program down, write your own allocation system with the behaviour you want.
You cannot portably rely on any such behavior of malloc()
. You can only rely on malloc()
giving you a pointer to a block memory of the given size which you can use until you call free()
.
Hmm, no. What malloc(3)
does internally is call the brk(2)
to extend the data segment if it's too small for given allocation request. It does touch some of the pages for its internal bookkeeping, but generally not all allocated pages might be backed by physical memory at that point.
This is because many OS-es do memory overcommit - promising the application whatever it requested regardless of available physical memory in hopes that not all memory will be used by the app, that other apps release memory/terminate, and falling back on swapping as last resort. Say on Linux malloc(3)
pretty much never fails.
When memory actually gets referenced the kernel will have to find available physical pages to back it up, create/update page tables and TLBs, etc. - normal handling for a page fault. So again, no, you will not get any speedup later unless you go and touch every page in that allocated chunk.
Disclamer: the above is might not be accurate for Windows (so, no again - nothing close to portable.)
No, there's no guarantee free() will not release the memory back, and there's no guarantee your second malloc will succeed.
Even platforms who "generally" don't return memory to the OS, does so at times if it can. You could end up with your first malloc succeeding, and your next malloc not succeding since in the mean time some other part of the system used up your memory.
Not at all. It's not portable at all. In addition, there's no guarantee that another process won't have used the memory in question- C runs on many devices like embedded where virtual memory addressing doesn't exist. Nor will it reduce fragmentation- you'd have to know the page size of the machine and allocate an exact number of pages- and then, when you freed them, they'd be just unfragmented again.
If you really want to guarantee malloced memory, malloc a large block and manually place objects into it. That's the only way. As for efficiency, you must be running on an incredibly starved device in order to save a few ifs.
malloc(3) also does mmap(2), consequently, free(3) does munmap(2), consequently, second malloc() can in theory fail.
The C standard can be read as requiring this, but from a practical viewpoint there are implementations known that don't follow that, so whether it's required or not you can't really depend on it.
So, if you want this to be guaranteed, you'll pretty much need to write your own allocator. A typical strategy is to allocate a big block from malloc (or whatever) and sub-allocate pieces for the rest of the program to use out of that large block (or perhaps a number of large blocks).
For better control you should create your own memory allocator. An example of memory allocator is this one. This is the only way you will have predictable results. Everything else that relies on obscure/undocumented features and works can be attributed to luck.
精彩评论