16

C (and C++) include a family of dynamic memory allocation functions, most of which are intuitively named and easy to explain to a programmer with a basic understanding of memory. malloc() simply allocates memory, while calloc() allocates some memory and clears it eagerly. There are also realloc() and free(), which are pretty self-explanatory.

The manpage for malloc() also mentions valloc(), which allocates (size) bytes aligned to the page border.

Unfortunately, my background isn't thorough enough in low-level intricacies; what are the implications of allocating and using page border-aligned memory, and when is this appropriate as opposed to regular malloc() or calloc()?

Jules
  • 14,200
  • 13
  • 56
  • 101
  • MSVC does not have `valloc` but it does have `_aligned_malloc` – Weather Vane May 31 '16 at 14:56
  • 2
    Short answer: in most architectures just because of **performance** but you will need an implementation specific function. – Adriano Repetti May 31 '16 at 14:58
  • 1
    This might be a helpful read: https://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.bpxbd00/rvallo.htm – JAL May 31 '16 at 15:13
  • I don't see `valloc` is standard C, nor POSIX. So your question is somewhat useless. Use `aligned_alloc` if you need a specific alignment. – too honest for this site May 31 '16 at 15:42
  • @Olaf if you could expand on that, I'm sure your comment could be a constructive answer. – Jules May 31 '16 at 15:51
  • @Jules: Done. Welcome to drop a comment. – too honest for this site May 31 '16 at 16:02
  • A clarification for those voting to close as primarily opinion-based; I was looking specifically for objective, technical answers relating to performance or functionality and scope, rather than answers related to code style or some other subjective parameter; the answers provided are thus far objective. – Jules May 31 '16 at 22:21

4 Answers4

15

The manpage for valloc contains an important note:

The function valloc() appeared in 3.0BSD. It is documented as being obsolete in 4.3BSD, and as legacy in SUSv2. It does not appear in POSIX.1-2001.

valloc is obsolete and nonstandard - to answer your question, it would never be appropriate to use in new code.

While there are some reasons to want to allocate aligned memory - this question lists a few good ones - it is usually better to let the memory allocator figure out which bit of memory to give you. If you are certain that you need your freshly-allocated memory aligned to something, use aligned_alloc (C11) or posix_memalign (POSIX) instead.

Wander Nauta
  • 18,832
  • 1
  • 45
  • 62
  • Nothing mentioned in that other question really applies to allocation with *page* alignment. – Nate Eldredge May 31 '16 at 15:10
  • The [glibc manual](https://www.gnu.org/software/libc/manual/html_node/Aligned-Memory-Blocks.html) curiously still mentions it, and even gives an implementation. – Wander Nauta May 31 '16 at 15:12
  • @iharob: On Ubuntu Xenial, which is the latest release, `valloc` is discussed in the `posix_memalign` man page, and `man valloc` will pull it up. – Nate Eldredge May 31 '16 at 15:22
  • @NateEldredge The OP stated that it was mentioned in the `malloc()` manual page. I am on Ubuntu Xenial now too and it's not there. But I see the confusion, I must have deleted part of the comment accidentally and didn't notice. – Iharob Al Asimi May 31 '16 at 15:25
5

Allocations with page alignment usually are not done for speed - they're because you want to take advantage of some feature of your processor's MMU, which typically works with page granularity.

One example is if you want to use mprotect(2) to change the access rights on that memory. Suppose, for instance, that you want to store some data in a chunk of memory, and then make it read only, so that any buggy part of your program that tries to write there will trigger a segfault. Since mprotect(2) can only change permissions page by page (since this is what the underlying CPU hardware can enforce), the block where you store your data had better be page aligned, and its size had better be a multiple of the page size. Otherwise the area you set read-only might include other, unrelated data that still needs to be written.

Or, perhaps you are going to generate some executable code in memory and then want to execute it later. Memory you allocate by default probably isn't set to allow code execution, so you'll have to use mprotect to give it execute permission. Again, this has to be done with page granularity.

Another example is if you want to allocate memory now, but might want to mmap something on top of it later.

So in general, a need for page-aligned memory would relate to some fairly low-level application, often involving something system-specific. If you needed it, you'd know. (And as mentioned, you should allocate it not with valloc, but using posix_memalign, or perhaps an anonymous mmap.)

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
-1

First of all valloc is obsolete, and memalignshould be used instead.

Second thing it's not part of the C (C++) standard at all.

It's a special allocation which is aligned to _SC_PAGESIZE boundary.

When is it useful to use it? I guess never, unless you have some specific low level requirement. If you would need it, you would know to need it, since it's rarely useful (maybe just when trying some micro-optimizations or creating shared memory between processes).

Jack
  • 131,802
  • 30
  • 241
  • 343
-1

The self-evident answer is that it is appropriate to use valloc when malloc is unsuitable (less efficient) for the application (virtual) memory usage pattern and valloc is better suited (more efficient). This will depend on the OS and libraries and architecture and application...

malloc traditionally allocated real memory from freed memory if available and by increasing the brk point if not, in which case it is cleared by the OS for security reasons.

calloc in a dumb implementation does a malloc and then (re)clears the memory, while a smart implementation would avoid reclearing newly allocated memory that is automatically cleared by the operating system.

valloc relates to virtual memory. In a virtual memory system using the file system, you can allocate a large amount of memory or filespace/swapspace, even more than physical memory, and it will be swapped in by pages so alignment is a factor. In Unix creation of file of a specified file and adding/deleting pages is done using inodes to define the file but doesn't deal with actual disk blocks till needed, in which case it creates them cleared. So I would expect a valloc system to increase the size of the data segment swap without actually allocating physical or swap pages, or running a for loop to clear it all - as the file and paging system does that as needed. Thus valloc should be a heck of a lot faster than malloc. But as with calloc, how particular idiotsyncratic *x/C flavours do it is up to them, and the valloc man page is totally unhelpful about these expectations.

Traditionally this was implemented with brk/sbrk. Of course in a virtual memory system, whether a paged or a segmented system, there is no real need for any of this brk/sbrk stuff and it is enough to simply write the last location in a file or address space to extend up to that point.

Re the allocation to page boundaries, that is not usually something the user wants or needs, but rather is usually something the system wants or needs.

A (probably more expensive) way to simulate valloc is to determine the page boundary and then call aligned_alloc or posix_memalign with this alignment spec.

The fact that valloc is deprecated or has been removed or is not required in some OS' doesn't mean that it isn't still useful and required for best efficiency in others. If it has been deprecated or removed, one would hope that there are replacements that are as efficient (but I wouldn't bet on it, and might, indeed have, written my own malloc replacement).

Over the last 40 years the tradeoffs of real and (once invented) virtual memory have changed periodically, and mainstream OS has tended to go for frills rather than efficiency, with programmers who don't have (time or space) efficiency as a major imperative. In the embedded systems, efficiency is more critical, but even there efficiency is often not well supported by the standard OS and/or tools. But when in doubt, you can roll your own malloc replacement for your application that does what you need, rather than depend on what someone else woke up and decided to do/implement, or to undo/deprecate.

So the real answer is you don't necessarily want to use valloc or malloc or calloc or any of the replacements your current subversion of an OS provides.

  • `in which case [memory] is cleared by the OS for security reasons` this is just plain wrong. There's no guarantee that the environment will behave this way. Additionally, I don't think this answer adds anything new to the question thread. – Jules Mar 24 '17 at 13:11
  • @Jules - what is wrong? If you (or malloc) use brk to grab new memory (that may have been used by some other user/process) it does get cleared by the OS, as not to do so is a security issue. In a modern OS, this is handled by the virtual memory system when allocating physical memory. It is not an answer to the question to say valloc is obsolete (whether it still is useful depends on the OS): valloc is faster than malloc under the (virtual memory allocation) conditions described, which is the answer to the original question of when to use valloc vs malloc, and indeed why we have valloc. – David M W Powers Apr 07 '17 at 09:13
  • `In a modern OS` -- you're making some very strong assumptions. There are many, many modern OSes (e.g. in embedded and some IoT applications) which do not enforce certain security measures that are taken for granted in commonly desktop- and server-use OSes. Incidentally, `valloc` can't be faster on the many OSes which have removed the implementation entirely because of deprecation. – Jules Apr 07 '17 at 12:56
  • @Jules - the question is not whether there are OS' that don't have VM or that don't enforce security, or where valloc wouldn't be faster, but when it is more appropriate to use valloc. If an embedded system doesn't support VM or doesn't enforce security, it is unlikely to require valloc. Similarly if it uses a VM-sensitive version of malloc that optimizes for the page boundaries of the VM system and avoids clearing memory that is allocated and not used, again, it is not going to require valloc. Traditionally however, people have written their own malloc because it was suboptimal. – David M W Powers Apr 07 '17 at 14:09