Hot answers tagged

20

If you care only about efficiency, here is a standard conforming and very efficient implementation: void* malloc(size_t sz) { errno = ENOMEM; return NULL; } void free(void*p) { if (p != NULL) abort(); } I'm pretty sure you won't find any faster malloc. But while still conforming to the standard, that implementation is useless (it never successfully ...


13

In my opinion, that is a horrible paradigm. I see absolutely no pros and at least three substantial cons. Needless code complexity Since malloc(0) can return NULL, the code has to be written to handle that anyway. And since malloc(0) can also produce a non-NULL result, the code also has to be written in a way to handle a non-NULL pointer. Pointer ...


12

There are multiple implementations of malloc and they can use very different algorithms. Two very widely used implementations are jemalloc and dlmalloc. In both cases the links have a lot of information about the thought process and trade-offs made in a general purpose allocator. Bear in mind a malloc implementation has very little information to go on, ...


11

The methods I've seen most are 2 and 3. The user supplied buffer is actually quite simple to use: char[128] buffer; mytype_to_string(mt, buffer, 128); Though most implementations will return the amount of buffer used. Option 2 will be slower and is dangerous when using dynamically linked libraries where they may use different runtimes (and different ...


7

As pointed out in this question, for the particular case of freeing memory immediately before terminating the program, free is a waste of time if your program runs on pretty much any modern operating system. You'll be making the allocator do the work of tracking down the memory and marking it as unused, despite the fact that the OS can free the memory in one ...


7

The "ideal" performance of an algorithm in people's minds is dependent on what the best option is out there. If you can do a "find" operation on a data structure in O(n log N) time, is that fast enough? Maybe it is. However, for many structures you can do a find in O(n), or even O(log n), so people will call your O(n log n) "slow." This isn't because it'...


6

First, malloc and free work together, so testing malloc by itself is misleading. Second, no matter how good they are, they can easily be the dominant cost in any application, and the best solution to that is to call them less. Calling them less is almost always the winning way to fix programs that are malloc-limited. One common way to do this is to recycle ...


6

The main problem with your malloc_quick() implemenation is, that it is not thread-safe. And yes, if you omit thread-support from your allocator, you can achieve a significant performance gain. I have seen a similar speedup with my own non-thread-safe allocator. However, a standard implementation needs to be thread-safe. It needs to account for all of the ...


5

"Slow" depends on the application. For some real-time applications (high speed machinery control, DSP, etc.), any non-bounded latency might be too slow, perhaps even leading to a catastrophic failure mode. For these applications, O(1) code is easier to verify as safe. O(logN) is only safe if N is strictly bounded and within requirements, and max(N) might ...


5

Here are some possible answers: IBM has patented their lock-free allocator... But then they also support Linux etc., so they might have an incentive to at least provide an implementation. And the XMalloc guys also filed for a patent on theirs. But I haven't [yet] found any patents (or patent applications) for NBmalloc. A more a localized issue is that M. ...


5

I'm not going to debug your code, there's not enough context to do this anyway, but I'm going to show you an idiom that you will probably find easier to use correctly. As a bonus, it will also be faster. Have a look at your loop body. You are allocating memory during each iteration and free it under certain circumstances depending on the overall control ...


5

Note that since C17/18 a subtle addition occurred: If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned to indicate an error, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object. ยง 7.22.3 1 Now when malloc(0) ...


4

sizeof(*test_buff) is computed at compile time and will evaluate to the size of a single element of test_buff. As test_buff is a buffer of char's, that element size is guaranteed to be 1. If I have to choose between the two options that you give, then only option 2 has useful behaviour. On the other hand, if there comes a time that you need to change the ...


4

It's not always the malloc and free performance that is an issue. You can run into problems with cache locality (or rather a lack of cache locality), and that can really hit performance if you are doing a lot of processing on the data. If you are worried you could switch to a memory-pooled scheme for all, most, or some parts of your API. I'm sure there ...


4

The usual answer for this thing is to wait until you can measure if there's a problem. My experience has been that malloc() is rarely an issue, but perhaps I also do more CPU-intensive work than you do, so malloc() isn't in the critical path. Definitely some people are constrained by the malloc performance. See, for example, https://github.com/blog/1422-...


4

You can draw the conclusion that you can't make an unlimited number of successful malloc() calls if you don't release memory in-between. You may have run 32 bit code in one case and 64 bit code in the other case. Compilers might allocate different amounts of memory for a small struct. malloc() might consume different amounts of memory for small allocations....


4

It is valid C code to call malloc in main and free in foo, but it is not considered best practice. If allocation and deallocation are done in different, unrelated, functions, then it becomes that much harder to tell if every block of memory obtained from malloc is actually freed (to prove you don't have a memory leak) or to prove that every pointer passed ...


3

Let's imagine for a moment all of your Items have the same size. A simple scheme would then be to have a pool of items, plus a bit for each one to mark whether it is allocated or not. Then the algorithm is simply "loop through the pool until you find an empty Item". This is a bitmap allocation scheme. A faster variation of this scheme is to have the free ...


3

Memory allocation by malloc is mostly a software function.  Typically the blocks allocated by software are too small for the MMU to manage.  For example, an MMU typically manages pages of size 4k or larger.  In fact, the larger the pages, the more efficient the hardware can be.  Hardware also manages pages on page aligned boundaries (...


3

If you really want to understand malloc internals, look into the source code. On Linux systems it is likely to be in GNU libc but there are other implementations of the C standard library (the musl-libc source code is nice to read) and of malloc (e.g. tcmalloc). Here is a very fast and simple malloc, but completely useless since always failing. Grossly ...


3

If the object lives to the end of the program, then you don't need to call free, but I would hold that it is still good practice to do so. The reason here is that, at the end of your code's execution, all of the memory will be free'd anyway, so there's no need to do so explicitly. Otherwise, yes; use free always.


3

It depends if you are in debug or release mode. In release mode, as Pedro said there is HeapAlloc/HeapFree which are kernel functions, while in debug mode (with visual studio) there is a hand written version of free and malloc (to which new/delete are re-directed) with thread locks and more exceptions detection, so that you can detect more easily when you ...


3

In as much as sizeof(*test_buff) will be sizeof(char), i.e. 1, I'd go with the 512.


2

Each call to malloc allocates memory on the heap and returns a pointer to it. If you do not call free on the returned pointer, the memory is not freed (so you get a memory leak). In most trivial cases it is not really necessary to call free (i.e. the application will probably run fine without it), but most people (rightly) consider not freeing the memory a ...


2

But I was wondering how these two criteria were related, namely, why there is a 'tradeoff' and why a faster heap makes it difficult for a smaller heap in size. When a request comes in you have to decide where to allocate it. The fastest thing to do would just be to allocate it on the top of the heap but that would lead to insane memory wastage. Basically ...


2

I think that the two SUT are not direct comparisons. I would not be surprised at any comparable difference when you consider all the variables: memory manufacture, motherboard architecture, compiler version (that compiled malloc), what the memory space application is like on the SUT at the time, etc etc etc ....... Try using your test harness to be more ...


2

If you compare a real malloc implementation with a school project, consider that a real malloc has to manage allocations, reallocations and freeing memory of hugely different sizes, working correctly if allocations happen on different threads simultaneously, and reallocation and freeing memory happen on different threads. You also want to be sure that any ...


2

All of the memory management techniques you described assume a singly-linked or doubly-linked list of free memory blocks. It is certainly possible to use something other than a linked list to manage memory, and there are memory managers that do just that, using an AVL tree or something similar. But then you're no longer talking about algorithms in terms of ...


1

In your specific context? I'd ask why you could not simply pass int down by value... But lets assume you are passing some complicated struct bar, that has the property of not being a nice stack resident... That's absolutely fine... Just ensure that the function foo(bar*) is clearly marked as taking responsibility for bar and that it will fulfil that ...


1

One possibility is that a 32 bit process on Linux has access to more memory (4GB) than a standard Windows 32 bit process (2GB). You haven't shown the definition of your Node class in the question, but from your usage it consists of 3 pointers and two data fields (possibly an int and a char). On a 32 bit build, that is a minimum of 17 bytes. With padding ...


Only top voted, non community-wiki answers of a minimum length are eligible