-1

I have a c++ program that makes a simulation. The simulation is large. It needs to be ran several times.

I probably didn't take into account some memory management guidelines like passing arguments by reference to functions to avoid copies of the same data to be wasting memory, and maybe other techniques I don't even know about. But it is too late to redo the whole program again (or maybe it won't even help).

I have a program

void main(){

//Simulation consuming a lot of memory.

};

I would like something like

void main(){
   for (int i=0;i<10000;i++){   
     //Simulation consuming a lot of memory (depending on i).
   };
};

But in such a way that after each loop of the for the memory used inside is released (probably except that which is used for the program and the counter i of the for).

The memory holds fine for one repetition of the loop but not for two.

I there a way this can be done?

Kae
  • 279
  • 2
  • 10
  • 4
    Your loop should accomplish that, provided the simulation does not leak memory. It sounds like it does, so you have to clean up the leaks. – Adam May 30 '14 at 04:17
  • 1
    This is way too vague. Are you leaking memory, or do the simulation just naturally require lots of memory? If you are leaking memory, you need to fix that first (look up smart pointers). BTW, `void main()` is not valid C++. – T.C. May 30 '14 at 04:18
  • 1
    A memory leak scenario but you must share some of your code with us, so we can tell you where to release memory or what techniques will be useful for you. – Sachamora May 30 '14 at 04:18
  • @Adam The problem is that I don't even know what is a memory leak (I can guess from the plain meaning of the words, but not idea what it means technically). – Kae May 30 '14 at 04:18
  • This is called memory leaks. You reserve memory, use it, but don't dispose it when you are done, so it's a snow ball that just keeps growing. You have to look after how exactly all this is happening. – Havenard May 30 '14 at 04:19
  • 1
    In c++, what Havenard said means that you have a `new` without a matching `delete`. – Adam May 30 '14 at 04:20
  • @Sachamora The code is huge. :S – Kae May 30 '14 at 04:20
  • 2
    http://codereview.stackexchange.com/ – Havenard May 30 '14 at 04:21
  • @Adam I see... I have lots of "new", and no delete. – Kae May 30 '14 at 04:21
  • @Adam I suppose that matching delete should be for the specific object the "new" created, isn't it? There is not way to do a global delete? – Kae May 30 '14 at 04:23
  • It sounds like a proper clean up is above your head. Another option is to run each iteration in another process. When a process exits all of its resources are cleaned up by the OS. The details on how to do this depend on your OS. – Adam May 30 '14 at 04:23
  • @Adam Windows 8, Visual Studio, Visual C++ ? – Kae May 30 '14 at 04:24
  • @Karene correct. Another option is to use smart pointers. These handle deletion for you automatically. Look up `shared_ptr`. That might be the easiest way to fix the code. – Adam May 30 '14 at 04:24
  • @Adam Searching that now. – Kae May 30 '14 at 04:25
  • not a Windows guy, can't help you with the best way to start a process there. But there should be a crapload of info online. Memory management is easy to screw up, and you sound like a novice. I'd try the process method first because it lets you leave the sim code untouched. Then go yell at whoever wrote it. – Adam May 30 '14 at 04:27
  • @Adam I will have to yell at myself. I wrote that mess. – Kae May 30 '14 at 04:28
  • 1
    @Karene use automatic allocation as much as possible (i.e. replace pointers to new'd stuff, with non-pointer variables) – M.M May 30 '14 at 04:30
  • In that case, you should go back and fix the leaks. `delete` any pointer you're done with, or use `shared_ptr` when you want automatic management. Don't use globals. – Adam May 30 '14 at 04:30
  • @Adam What if I make an object that has a single function that contains the whole code of the (of the main() of the) simulation. Then in my main (inside the "for") I create that object with the shared_ptr and make it run its function. Would the destruction of the object destroy also all the memory allocation that its function made? – Kae May 30 '14 at 04:31
  • 1
    Matt is right, there is a growing movement that there are very few reasons for a "naked" `new`. In other words, every `new` should go directly into something like a `shared_ptr`. – Adam May 30 '14 at 04:32
  • yes, a `shared_ptr` deletes whatever it points to when the last reference goes out of scope. – Adam May 30 '14 at 04:33
  • @Adam Good! Then I will try that. It would be less changes to do than to fix all the "new" that are all around the program (many of them!). – Kae May 30 '14 at 04:34
  • @Karene Um, it won't work the way you want it to. It'd delete the empty object but not anything allocated by the function. – T.C. May 30 '14 at 04:35
  • @T.C Ohww... Then I guess I will need to write another c++ program that runs the .exe of my simulation several times. The memory seems to hold well for one run of the simulation. For two passes it fills up. – Kae May 30 '14 at 04:37
  • 3
    I don't know if you're coming from a Java or C# background but my suggestion is to just stop using `new` in C++. If you need dynamic containers, data structures, or strings look first in the C++ standard library. When you have no other choice but to use `new` you have to think about resource management for your objects. That means construction, copying, assignment, and destruction. – Blastfurnace May 30 '14 at 04:50
  • @Karene: writing another c++ program may be overkill... your OS shell (e.g. `bash` - `i=0; while (( $i < 20 )); do ./your_app $i; let i+=1; done`, `cmd.exe`) probably allows this very easily - you can accept `i` ala `int main(int argc, const char* argv[]) { if (argc != 2) exit(1); int i = atoi(argv[1]); ... }` – Tony Delroy May 30 '14 at 05:05
  • @TonyD Could you put this as an answer. I don't think I am understanding it. Does that go in a bash file? – Kae May 30 '14 at 05:16
  • @Blastfurnace Thanks. I shall take it into account in the future. I am actually coming from not using an actual programming language for more than 20 years. I just began learning C++ four weeks ago. I have rough theoretical knowledge of OOP but zero concrete practice. – Kae May 30 '14 at 05:21
  • @Karene: done... hope it's clearer now. Cheers. – Tony Delroy May 30 '14 at 05:40

1 Answers1

2

On UNIX/Linux, you could create a bash shell script to call your C++ program the required number of times, say run_my_app.sh with the following content:

i=0
while (( $i < 10000 )); do
    ./my_app $i
    let i+=1
done

Then make it executable with chmod +x run_my_app.sh.


On Windows, do the same for the cmd.exe "shell", creating run_my_app.bat with:

for /l %i in (0,1,9999) do my_app %i

You can add the full path to my_app if you need to, e.g.: c:\dir1\dir2\my_app instead of my_app. You don't need to do anything to make it executable - that's implied by the .bat extension.


Then modify your C++ program as follows:

#include <cstdlib>

int main(int argc, const char* argv[])
{
    if (argc != 2)
    {
         std::cerr << "usage: " << argv[0] << " i\n"
              "run the simulation iteration number <i>.\n";
         exit(EXIT_FAILURE);
    }

    int i = std::atoi(argv[1]);

    ...simulation...
}
Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • 1
    This is for Linux isn't it? I only have Windows at the moment. :S Thanks, though. – Kae May 30 '14 at 05:58
  • @Karene: Windows version added. – Tony Delroy May 30 '14 at 06:18
  • My main looks like int _tmain(int argc, _TCHAR *argv[]) When I added your code, it said that it cannot convert from _TCHAR* from constant fiels – Kae May 30 '14 at 06:27
  • @Karene: my code follows the C++ Standard... _TCHAR is not Standard C++ and I don't know about it. I can only suggest you try a different compiler or google/ask about that problem separately. You can presumably find an example of a `_tmain`/`_TCHAR` monstrosity's arguments being parsed without much effort. Cheers. – Tony Delroy May 30 '14 at 06:38
  • It is working now. But I am having a problem. The atoi is ony taking the first digit of the %%i. – Kae May 30 '14 at 15:50
  • @Karene: that sounds very strange... a bit of searching suggests this tmain/TCHAR thing is doing something non-Standard: accepting "wide" characters (unicode) - there's a discussion about it [here](http://stackoverflow.com/questions/895827/what-is-the-difference-between-tmain-and-main-in-c). I don't know how to work with unicode strings - not something I've ever had to do and frankly the idea of wading into that mess sends a shiver down my spine, but hopefully now you know what the problem is you can find a solution or ask a question about tmain and unicode. – Tony Delroy May 30 '14 at 22:55
  • It was indeed a problem with those tmain and Tchar. I changed them to main and char, and now it worked. The argv was only inputting the first character of the argument. – Kae May 31 '14 at 12:56
  • @Karene: thanks for letting me know. Hope the simulation's running ok then. Cheers. – Tony Delroy May 31 '14 at 14:54