dhcarmona
dhcarmona

Reputation: 412

C++ Find out dynamic memory in use

Hi and thanks beforehand for your help.

First of all, this is for a homework, but I've done almost everything I need. We were asked to implement a linked list class, do some adding and deleting on it, and calculate it's memory usage.

I have the lists done, and the adding and deleting (from a text file). All of that is done. However, I'm stuck on calculating the memory usage.

I've been looking for an easy way to do this, and I haven't found anything. What I actually need is some method that will return the amount of dynamic memory in use. That's all. I've found several tools to find memory leaks, but I think they are just over the top, for what I need.

I also found a method to find the amount of memory a process uses, but I don't need that either. I just need to find out the total amount of memory used, like in the Task Manager.

I'm using Virtual Studio on Windows 7. Thanks for your help!!

EDIT

Here is exactly what the teacher asked us to do (translated from spanish):

"Every time the loading operation (from the text file, unrelated) is realized, the program should display how much memory is available in the Heap (memory for allocating), and how much is available before the loading of the file."

Upvotes: 5

Views: 5228

Answers (6)

Harry Johnston
Harry Johnston

Reputation: 36348

Taking the teacher's question as literally as possible, you can do this using the HeapWalk function. This allows you to calculate both free and used space in the heap of your choice (you probably want the process default heap, see GetProcessHeap).

Since the heap will expand as needed (within the constraints of the process virtual address space and available virtual memory) this information isn't usually particularly useful in practical terms. But it may serve your needs.

Upvotes: 1

Irfy
Irfy

Reputation: 9607

How about you track your memory manually? In every constructor:

global_size += sizeof(*this);

and in every destructor:

global_size -= sizeof(*this);

Caveats:

  • If you use inheritance, you need to make sure not to count object size multiple times.
  • Only structures you modify with the above code will be counted, not any other structures like strings or arrays (though if the array contains your structure instances, they will still be counted).

At any point in time, global_size will have the amount of memory taken by the structures you track.

Alternatively, you can replace the global new/delete operators:

void* operator new(std::size_t) throw (std::bad_alloc);
void* operator new[](std::size_t) throw (std::bad_alloc);
void* operator new(std::size_t, const std::nothrow_t&) throw();
void* operator new[](std::size_t, const std::nothrow_t&) throw();
void operator delete(void*) throw();
void operator delete[](void*) throw();
void operator delete(void*, const std::nothrow_t&) throw();
void operator delete[](void*, const std::nothrow_t&) throw();

And do the memory-counting magic in them. See also How do I call the original "operator new" if I have overloaded it?

See also How to get memory usage at run time in c++?

Upvotes: 2

Łukasz Milewski
Łukasz Milewski

Reputation: 1911

I found GetProcessMemoryInfo function (Windows)

http://msdn.microsoft.com/en-us/library/windows/desktop/ms683219(v=vs.85).aspx

Use _getpid() when it asks you for process id

http://msdn.microsoft.com/en-us/library/t2y34y40.aspx

I don't use Windows myself, but looks like it should work.

Under Linux you could query /proc/PID/statm

Upvotes: 3

user405725
user405725

Reputation:

Well, the solution for your problem really depends on what exactly you are asked to do. There is a big difference between an overall memory usage of the application and a memory that is being used by a linked list. If you need to know how much memory your linked list is using, you have to multiple a number of nodes by the size of the single node. Here is a simple example (in C, you will have to adjust it a bit to make it C++ compatible):

#include <stdio.h>
#include <stdlib.h>

struct list_node {
    int data;
    /* ... other stuff ... */
    struct list_node *next;
};

int main(void)
{
    int i;
    struct list_node *list;
    struct list_node *node;

    /* Create a single linked list with 5 elements */
    node = list = malloc(sizeof(struct list_node));
    if (!node)
        abort(); /* Not enough memory */
    node->data = 0;

    for (i = 1; i < 5; ++i) {
        node->next = malloc(sizeof(struct list_node));
        if (!node->next)
            abort(); /* Out of memory */
        node = node->next;
        node->data = i;
        node->next = NULL;
    }

    /* Print a list, count a number of nodes, and estimated memory usage. */
    i = 0;
    for (node = list; node != NULL; node = node->next) {
        ++i;
        printf("Node %d\n", node->data);
    }

    printf("%d nodes use %ld bytes of memory (%ld per node).\n",
           i, i * sizeof(struct list_node), sizeof(struct list_node));

    /* TODO: Free resources... */
    return 0;
}

In this example, 5 nodes were created to form a linked list. So the total amount of memory that is needed for the list is 5 * sizeof(struct list_node).

Of course, when you allocate memory using malloc() function, it allocates an extra space. For example, it needs to store an information somewhere in order to know how many bytes was allocated for a given pointer in order to free it, it also takes care of alignment, and may allocate more space than needed so that the next time you call malloc() the memory will already be there.

So if you really want to know all those details, then you need to use operating system specific interface to determine how much virtual memory your application is using. In particular, you need two numbers - memory usage before and after linked list creation. Unfortunately, there is no standard API for that. But here is a good Q&A that can help you get around your platform and solve this - How to determine CPU and memory consumption from inside a process?

It is most likely that your teacher wanted you to do the simple thing. But if you do both - that will only be a plus for you.

Good luck!

Upvotes: 0

cooky451
cooky451

Reputation: 3510

You can overload the global operator new and delete and keep track of that.

Upvotes: 1

Nicol Bolas
Nicol Bolas

Reputation: 474376

You're really overthinking this. You were asked to find out the memory that your list uses. That's the sum of all of the nodes in your list * the size of each node and its contents.

Upvotes: 2

Related Questions