Why you should use talloc for your next C project
blogs.fedoraproject.org
blogs.fedoraproject.org
Tridge fluffed up halloc to make the API more fit and convenient for Samba code, and talloc came out. I still like my version better though because it is simpler and (subjectively) more elegant.
It doesn't look like talloc is any better.
The thing is my app is already not doing a lot of work per request so almost any speedup is noticeable.
My understanding of halloc and talloc is that they are general purpose allocators. A pure library approach - that is, without source code analysis and code generation - won't be able to tailor the allocation scheme based on the data structures themselves.
When two blocks are explictly tied into a parent-child relationship, it gives the allocator valuable locality information. It is another matter that halloc separates allocation and block binding steps, so the relationship information is not available at the allocation time, and so it cannot utilize these locality hints.
The second thing is locality. An allocator like halloc could theoretically utilize the fact that two blocks are explictly marked as related and allocate them close to each other. However, for this to work the allocation function needs to be passed a pointer to the parent block, which is not the case with halloc. So the API needs to change, the implementation needs to change too, and then it will no longer be a light implementation of a simple idea, but something else.
http://mongrel2.org/dir?ci=4ff647658e12c6f4&name=src/mem
edited to add (for third parties): iirc, halloc is mainly used by mongrel2 in things like the routes table, where it makes the code for maintaining the trie much cleaner.
You are correct in that you can just write constructors and destructors, but then you still need to worry about error handling, double-frees and whatnot. With an allocator like talloc, you just state the relationships during the allocation, and afterwards only worry about the high-level structure.
One thing which can be somewhat cumbersome is the need to pass around those "contexts"; for example, if you allocate an array of some struct, and you need to allocate additional memory inside that struct, your context will presumably be the array, and so you need to have access to it. One solution I have found which is helpful in most, but not all, situations is to use the wonderful container_of[1] macro, which enables you to do upcasting using some pointer trickery. And of course, it does cost some performance as they say on their homepage.
tmalloc() adds a layer of complexity that is unhealthy to C programs. Are the few seconds you save by using tmalloc() really worth the hours spent to debug memory leaks 6 months later when the project got big and complex with multiple collaborators ? No.
Introducing side-effets under the table is the best way to confuse other C programmers when they read your code. It's not worth it.
Memory management is part of C, and will always be. If you don't like it, switch to another language.
I'm curious, did you just find HN or did this particular article motivate you to create an account?
(I wish there were a private message system.)
C forces you to explicitly communicate who is responsible for allocating and freeing each piece of memory. Isn't talloc just providing a mechanism that helps with this?
If talloc is part of a project's memory management policy, contributors not using it consistently are by definition not following the policy consistenly. This would be a problem regardless of mechanism.
You get kmalloc() and kfree(), which are very similar to malloc() and free(). (Okey you also get kmem_cache_alloc()/kmem_cache_free() which gives you the ability to provide a ctor/dtor, but they are explicit)
tmalloc() does too much: The day you have some memory corruption / leak, you'll start being scared of using tmalloc().
As for large project with collaborators: if the project doesn't already have coding standards or doesn't have a code review process for new members then they're already headed down a bad path. And anyone blindly introducing talloc into an existing project without first getting agreement from other participants and taking steps to smooth integration is irresponsible.
The issues you give aren't reasons to dismiss talloc. Bugs, implementation flaws, design limitations are some valid reasons. By your argument, anything layered on top of the C standard library should be avoided.
2) Absolutely
3) No. it's just that memory management related issues are really nasty. On the other hand, adding a new printf() function won't do much harm.
Edit: Also, how is this better than doing something like this
struct some_complex_struct {
...
};
free_some_complex_struct(struct some_complex_struct * scs) {
...
}According to the article, talloc is a malloc wrapper. If that's the case, why shouldn't you be able to drop in whatever allocator you want? talloc should still use it under the covers.
void * talloc_steal(const void * new_ctx, const void * ptr);
The talloc_steal() function changes the parent context of a talloc
pointer. It is typically used when the context that the pointer is
currently a child of is going to be freed and you wish to keep the
memory for a longer time.
NOTE: It is possible to produce loops in the parent/child relationship
if you are not careful with talloc_steal(). No guarantees are provided
as to your sanity or the safety of your data if you do this.
There's also talloc_reparent where you explicitly choose the parent to change.http://www.gnu.org/s/hello/manual/libc/Obstacks.html
seems like a very similar concept / means to an end?
GPL v3.
Too much legal baggage for such a small piece of functionality.
Good point, I thought that the requirement was substitutability and dynamic linking was just given as an example of how a library can be substitutable, but it appears that dynamic linking is sufficient.
> and also explicitly covers the inclusion of bits from header files.
It's not clear to me exactly the meaning of these sections; if including bits from header files is truly allowed, then you could effectively circumvent the substitutability goal by simply inlining the whole library.
> That said, I don't write proprietary software, so that doesn't affect me. :)
I don't either, but I write a BSD-licensed library that I absolutely want to be usable with proprietary software without any difficulty.
You can satisfy the requirement without dynamically linking (by shipping object files or source code instead), making dynamic linking sufficient but not necessary. In practice, though, nobody seems to attempt anything other than dynamic linking against an LGPL library, or shipping enough source code for static linking (even if not all the source code).
> It's not clear to me exactly the meaning of these sections; if including bits from header files is truly allowed, then you could effectively circumvent the substitutability goal by simply inlining the whole library.
Substitutability represents a technical goal, and the library has to support that goal for it to prove useful. If the library provides the entirety of its functionality via inlines in header files, they clearly don't care about substitutability. And if you modify the library to move all of it into header files, you still have to supply the source for the modified version of the library, so you've broken substitutability but you haven't broken the copyleft. As far as I can tell, the LGPL's goal of substitutability seems primarily aimed at cases where you don't intend to substantially modify the library; after all, you can also change the library's API/ABI and thus make the original no longer substitutable. (Personally, I don't really see the point of the substitutability provisions anymore; I really just want a copyleft on the library itself.)
> I don't either, but I write a BSD-licensed library that I absolutely want to be usable with proprietary software without any difficulty.
Fair enough. However, in that case the copyleft on the LGPL software seems equally onerous, since users of your library would need to ship the source of talloc, even though they don't need to ship the source of your library. (One other interesting provision: the users of your library couldn't use a license that prohibits reverse-engineering.)
In any case, yes, talloc's license effectively makes it unusable by libraries that want to provide an all-permissive license. If you really want to use talloc, you might consider writing to the authors of talloc; they might prove sympathetic to the needs of a BSD-licensed library, and grant a suitable exception. (Personally, I'd like to see some standard wording for an exception similar to the one used in UPX, namely that you can use it under an all-permissive license as long as you use an unmodified version.)
http://ccan.ozlabs.org/info/talloc.html talloc is LGPL v2
The ccan version http://ccan.ozlabs.org/info/talloc.html says it is based upon svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/talloc revision 23158 , and is LGPLv2.
I believe http://talloc.samba.org/talloc/doc/html/talloc_8h_source.htm... is the latest version, 2.0.5 from 10-Jan-2011. That version does appear to be LGPLv3.
(Note that both appear to have the "or (at your option) any later version" clause, but that's largely irrelevant in this case.)
Though I do understand, there are some very special projects that can't use C++, and must use C. I'd say in most cases, the extra machinery you get with C++ outweighs the small performance penalty you get by going with straight C.
These functions are to be used with particular conditions which aren't clearly specified. When the conditions are met then it is a clear benefit to use them. But these add complexity and new pitfalls to inexperienced programmers.
For better tools, check out Instruments, MallocDebug or leaks. Or read Apple's Memory Usage Performance Guidelines, specifically the "Finding Memory Leaks" section. [1] Apple's Technical Note TN2124 "Mac OS X Debugging Magic" even has, in the Cocoa section, an example of how -retainCount can be misleading and confusing. [2]
Nowhere does Apple advise Cocoa developers to avoid ref-counting. Cocoa's ref-counting/GC'd memory management system is considered a huge advantage for the platform.
[1] http://developer.apple.com/library/mac/#documentation/Perfor... [2] http://developer.apple.com/library/mac/#technotes/tn2004/tn2...