0

I've found unexpected results about memory management running the following (sample) code:

#include <stdint.h>
#include <iostream>
#include <vector>

#define BIGNUM 100000000

// sample struct
struct Coordinate {
    uint64_t x;
    uint64_t y;
    uint64_t z;
    Coordinate() {
        x = 1ULL;
        y = 2ULL;
        z = 3ULL;
    }
};

int main() {
    std::vector<Coordinate*>* coordinates = new std::vector<Coordinate*>();

    for (int i = 0; i < BIGNUM; ++i)
        coordinates->push_back(new Coordinate());

    // block 1
    for(std::vector<Coordinate*>::iterator it = coordinates->begin(); it != coordinates->end(); ++it)
        delete(*it);

    // block 2
    delete(coordinates);

    std::cout << "end\n";
    std::cin.get();

    return 0;
}

On my Ubuntu 14.04:

enter image description here

The command ps aux --sort -rss was performed on std::cin.get(); 4 times, with small differences:

1) program as is

2) with block 1 commented (basically no delete on every vector's element)

3) with block 2 commented (so no delete on vector)

4) both both blocks 1 and 2 commented.

With my (big) surprise test 1) and 2) have almost the same RSS / VSZ results. In simple words it seems that delete(*it); doesn't work properly (doesn't free memory). Same conclusion can be achieved with 3) and 4).

On Windows XP (running in VirtualBox) everything is fine and memory is 0-2 MB running the program as is.

c.bear
  • 1,197
  • 8
  • 21
  • Why are you using `new` `delete` here in first place?? – πάντα ῥεῖ Aug 09 '15 at 14:43
  • 1
    @πάνταῥεῖ I've found the issue in a more complex program. Here is just a simplified example! – c.bear Aug 09 '15 at 14:46
  • Your _simplified_ example is probably over simplified, because it doesn't reproduce the described behaviour. – πάντα ῥεῖ Aug 09 '15 at 14:48
  • 1
    I don't get what you mean. I'm just saying that `delete(*it);` seems not working properly, because *ps* returns same _VSZ/RSS_ when delete is commented and when it is not – c.bear Aug 09 '15 at 14:54
  • As for your _bigger context_ you made sure following [The Rule of Three](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) properly everywhere, did you? Especially regarding `Coordinate`. – πάντα ῥεῖ Aug 09 '15 at 14:58
  • Just FYI: You allocate so much that in this example program that `std::bad_alloc` is actually thrown on my machine. – Christian Hackl Aug 09 '15 at 15:14
  • @ChristianHackl so curious. I got 16GB of memory, maybe you are running just 4GB with no swap? – c.bear Aug 09 '15 at 15:16
  • 1
    @c.bear: 4GB memory, Windows 7, standard swap settings (3562 MB). I guess this notebook is slowly getting old for new-generation software... :) – Christian Hackl Aug 09 '15 at 15:22
  • @ChristianHackl oh, on i7 everything happens in the blink of an eye – c.bear Aug 09 '15 at 15:29

1 Answers1

3

Just because delete frees memory doesn't mean that the memory is immediately released back to the operating system for general use. Memory management on modern OSes is just not that simple.

There's nothing wrong here other than your assumptions!

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • That's what I thought too. But I really MUST free that memory in my real scenario, since I'm working on a really huge memory consuption program (16GB are eaten very fast). Is there any compiler option or something that can help me? – c.bear Aug 09 '15 at 15:15
  • 2
    @c.bear: No you don't. Your OS is intelligent enough to work this out on its own. Just leave it to do its job and don't put too much stock in these figures you're seeing from `ps`. Consider purchasing a book on operating systems and virtual memory schemes. – Lightness Races in Orbit Aug 09 '15 at 15:16