Hi everybody,
I am writing a scientific program with lots of math calculations in linux.
I use exit() to stop a the normal program execution if something unexpected happens ( a parameter is not found in the data file, the data file has a wrong format, a file cannot be opened, memory cannot be allocated....).
The problem is that, as far as I have understood, it is not guaranteed that the allocated memory is freed after calling exit(). Apparently it depends on the operating system.
Therefore I would like to write the program in a way that the memory is always freed.
Is there a way to that?
I was considering creating a "memory table" by defining a global pointer such as void*, void** or void*** and update it every time memory is allocated or released. Before interrupting the program execution I would then have to delete everything which is in my memory table.
Any suggestion? I was considering using auto_ptr but it would not work for vectors or matrix
Jsmith, are you sure? I am not an expert, not at all! But last year i posted a thread in another forum and got loads of replies saying that it depends on operating system and not all operating systems would free the allocated memory (with new and delete[] ). As my numerical program will crash , i would end up rebooting the pc or workstation all the times!
Unix (Linux, BSD etc) and 32/64bit-Windows clean up the mess left by an application. But this is not generally true, some OSs may be little more than file/memory managers. Additionally, further thought needs to be given to the treatment of shared memory.
I posed the questions above because if dynamic memory is managed by a class, then you just need to think about the scope of the classes. If it's managed directly within worker functions, extra care is necessary.
But the crux of the matter is the structure of your code. You program should terminate thru main, or the main entry point. Calling abort() or exit() is akin to using goto. It's common practice on Unix from what I've seen, and they get away with it because the OS offers so much protection to the programmer. But if you came from a more primative background, you simply couldn't/wouldn't do that.
Can you give an example where returning cleanly thru the stack using error codes (or an exception) is problematic?
AFAIK, even the crappiest of OSs will free the memory allocated by a process when the process ends. I think the programmer should assume this will happen.
Of course, that doesn't mean it's OK not to free allocated memory.
I'm getting more lost in all this.
I tried to use vector<char> and vector<vector<char>>, to try to overcome the problem but i got into even bigger mess.
I have 4Gb Ram and 7.8Gb swap. It works fine with new and delete till i allocate 11Gb of char. If I use vector throws an exception with 11Gb, but with 10Gb doesn't throw and exception but freezes my laptop!
On the other hand I can see that using vector it cleans up all the memory on exit.
On the other hand I can see that using vector it cleans up all the memory on exit.
No, it doesn't. It destructs the vector at the end of f().
Keep in mind that a vector needs n*sizeof(T) bytes free and adjacent. Why don't you try creating 10240 vectors, each 1 MB long? In any case, I can assure you whatever OS you're using on you laptop, the memory will be freed when the process ends.
But the crux of the matter is the structure of your code. You program should terminate thru main, or the main entry point. Calling abort() or exit() is akin to using goto. It's common practice on Unix from what I've seen, and they get away with it because the OS offers so much protection to the programmer. But if you came from a more primative background, you simply couldn't/wouldn't do that.
Can you give an example where returning cleanly thru the stack using error codes (or an exception) is problematic?
In main I create classes and/or pointer to classes. For example one of the classes is in charge of reading the data files. In that class I dinamically allocate a few char matrices in which I store the data from the files. If, during such a process, in one of the files the syntax of data are wrong (or I do not have any more free memory), i need to stop the program execution to allow for changes in the data file. I cannot simply stop by calling the destructor because, unless the problem occurs at the real end, only some of the matrices have been allocated. That is why I was considering creating a void pointer vector with the memory addresses of what has really been allocated.
I don't see how throwing exceptions alone could help, as I would always need to know what has already been allocated in the class.
In this instance, exceptions can help. Think of it this way. When you define a subsystem or class, you not only define what it does, but what can go wrong. As such, you can define small set of exception classes that can communicate the error. And with a class, you can pack all sorts of information that assists in the diagnosis or cause of the error.
So you'd instantiate your class, call an initialise method, and possible catch an exception if some crucial resource was unavailable.
A different approach is that used by OpenSSL. OpenSSL is a C library and is made up of layers. When an error occurs, each layer adds it's view of what went wrong to a stack, and the whole thing is available to the caller. For example, the attempt to create a certificate may fail because you've run out of disk space in the layer that interfaces with the file system. The layer that called that may say failed to write file, and the layer above may say failed to create certificate. The caller gets a failure code, but then can query this error stack.