patriot
patriot

Reputation: 39

Possible memory leak with malloc()

I have this code:

#include <malloc.h>

int main()
{
    int x = 1000;

    //~600kb memory at this point
    auto m = (void**)malloc(x * sizeof(void*));
    for (int i = 0; i < x; i++)
        m[i] = malloc(x * sizeof(void*));

    for (int i = 0; i < x; i++)
        free(m[i]);

    free(m);

    //~1700kb memory at this point
    return 0;
}

When program starts memory consumption is about ~600kb, and when it ends ~1700kb. Is it memory leak or what?

Upvotes: 3

Views: 1397

Answers (4)

oo_miguel
oo_miguel

Reputation: 2379

free() and malloc() are part of your Standard Library and their behavior is implementation dependent. The standard does not require free() to release once acquired memory back to your Operating System.

How the memory is reserved is plattform specific. On POSIX systems the mmap() and munmap() system calls can be used.

Please Note that most Operating Systems implement Paging, allocating memory in chunks to processes anyway. So releasing each single byte would only pose a performance overhead.

Upvotes: 1

SergeyA
SergeyA

Reputation: 62603

When you are running your application under management of operating system, the process of memory allocation in languages like C/C++ is two-fold. First, there is a business of actually requesting memory to be mapped into process from operating system. This is done through OS-specific call, and an application needs not bothering about it. On Linux this call is either sbrk or mmap, depending on several factors. However, this OS-requested memory is not directly accessible to C++ code, it has no control over it. Instead, C++ runtime manages it. The second thing is actually providing a usable pointer to C/C++ code. This is also done by runtime when C++ code asks for it.

When C/C++ code calls malloc(or new), C++ runtime first determines, if it has enough continuous memory under it's management to provide a pointer to it to application code. This process is further complicated by efficiency optimizations inside malloc/new, which usually provide for several allocation arenas, used depending on object sizes, but we won't talk about it. If it has, the memory region will be marked as used by application, and a pointer will be returned to the code.

If there is no memory available, a chunk of memory would be requested from the OS. The size of the chunk normally will be way bigger than what was requested - because requesting from OS is expensive!

When the memory is deleted/freed, C++ runtime reclaims it. It might decide to return memory back to OS (for example, if there is a pressure in terms of total memory consumption on the machine), or it can just store it for future use. Many times memory will never be returned to the OS until process exits, so any OS-level tool will show process consuming memory, even though the code delete'd/freed it all!

It is also worth noting that usually application can request memory from OS bypassing C++ runtime. For example, on Linux it could be done through mmap call or, in bizarre cases, through sbrk - but in latter case you won't be able to use runtime memory management at all after this. If you use those mechanisms, you will immediately see process memory consumption growing or decreasing with every memory request or return.

Upvotes: 0

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123114

Is it memory leak or what?

No. You have each malloc matching a free and if I dont miss something you have no memory leak.

Note that what you see in the process manager is the memory assigned to the process. This is not necessarily equal to the memory actually in use by the process. The OS does not immediately reclaim it when you call free.

If you have a more complex code you can use a tool like valgrind to inspect it for leaks. Though, you better dont use manual memory managment at all, but use std containers instead (eg std::vector for dynamic arrays).

Upvotes: 4

John Zwinck
John Zwinck

Reputation: 249502

malloc() acquires memory from the system using a variety of platform-specific methods. But free() does not necessarily always give memory back to the system.

One reason the behavior you're seeing might exist is that when you first call malloc() it will ask the system for a "chunk" of memory, say 1 MB as a hypothetical example. Subsequent calls will be fulfilled from that same 1 MB chunk until it is exhausted, then another chunk will be allocated.

There is little reason to immediately return all allocated memory to the system just because the application is no longer using it. Indeed, the most likely possibilities are that (a) the application requests more memory, in which case the recently freed pieces can be doled out again, or (b) the application terminates, in which case the system can efficiently clean up all its allocated memory in a single operation.

Upvotes: 7

Related Questions