4

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."

dhcarmona
  • 402
  • 2
  • 10
  • 29

6 Answers6

3

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

Łukasz Milewski
  • 1,897
  • 13
  • 14
2

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.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Actually you would think that, and that would be the most logical thing to do. But I was specifically asked for the total amount of dynamic memory allocated in the system... – dhcarmona Mar 04 '12 at 22:46
  • @dhcarmona: Actually I think Nicol is correct here. The term "dynamic memory allocated in the system" is a bit vague to me (could mean a lot of things). I think your teacher just wants to know how much dynamic memory is allocated in the list. Look up sizeof() – Martin York Mar 04 '12 at 22:57
  • @LokiAstari: I totally get what you mean ^^ and I would do that, if the teacher hadn't used the TaskManager example. He told us that he wanted the program to show how much system was used just like the manager, just more accurately. (in KB, not MB) – dhcarmona Mar 04 '12 at 23:08
  • @dhcarmona: There is no such thing as "dynamic memory allocated in the system". The system tracks physical memory and virtual memory of various kinds. But at the system level, the semantic meaning to the program (that it's associated with a dynamic structure) is lost. Applications are free to allocate such memory many different ways. This sounds like an incoherent requirement. (And a teacher should know that this is not a sensible way to figure out if your destructors are working or what their effect is.) – David Schwartz Mar 04 '12 at 23:12
  • @DavidSchwartz: Thanks for the clarification, I updated the question to include the exact requirement the teacher gave to us. – dhcarmona Mar 04 '12 at 23:23
  • @dhcarmona: Then your teacher has asked you to do something which is *impossible* without access to platform-specific APIs. If he hasn't told you what those APIs are or where you might go to search for them, then he's set you all up to fail. – Nicol Bolas Mar 05 '12 at 01:42
  • @NicolBolas Actually I think he has. It wouldn't be the first time a teacher asks us to do something they have no idea how it's done, or if it's even possible. I ended up using an API from Microsoft to get what I needed. Thanks for all the help! – dhcarmona Mar 05 '12 at 02:23
2

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++?

Community
  • 1
  • 1
Irfy
  • 9,323
  • 1
  • 45
  • 67
  • That's the point... I need the total amount of system memory used, not just the one used by my structures. But thanks ^^ – dhcarmona Mar 04 '12 at 22:59
  • This does not not account for dynamically allocated arrays, strings, etc. – jweyrich Mar 04 '12 at 23:01
  • 2
    In that case you should overload the global `new` and `delete` operators (including array variants) and do this memory tracking there. – Irfy Mar 04 '12 at 23:11
  • @dhcarmona I gave you further hints on counting allocated memory with custom new/delete operators. – Irfy Mar 04 '12 at 23:26
  • @jweyrich Yes, the original code would only track *hand-made* structures, like the nodes of a linked list. The global new/delete would track everything though. – Irfy Mar 04 '12 at 23:27
1

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

cooky451
  • 3,460
  • 1
  • 21
  • 39
1

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.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
0

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!

Community
  • 1
  • 1
  • Thanks for the help ^^ If you would check the edit I did on the question, I'd appreciate it. I understand how the memory used by the program itself is different to the one used by the list, but that's not what I was asked for. – dhcarmona Mar 04 '12 at 23:21