I am having issues with my program throwing a large number of memory allocation exceptions and I am having a very hard time diagnosing the problem...I would post code, but my program is very large and I have proprietary information concerns, so I am hoping to get some help without posting the code. If you plan on responding with some form of SSCCE comment, just stop reading now and save both of us some time. This is a case where I cannot post succinct code - I will try to be as clear and concise as possible with my problem description and some specific questions.
Program Background - my program is basically a data cruncher. It takes a bunch of data tables as inputs, performs calculations on them, and spits out new data tables based on the calculation results. All of my data structures are user-defined classes (consisting of int, double and string types with vector containers for arrays). In all cases, I initiate instances of class variables without the use of new and delete.
Problem Description - my program compiles without warnings, and runs fine on smaller datasets. However, once I increase the dataset (from a 20x80 array to 400x80), I start throwing bad_alloc exceptions (once I've processed the first 35 entries or so). The large datasets runs fine in 17 of my 18 modules - I have isolated one function where the errors are occurring. The calculations needed for this function would result in about 30,000 rows of data being created, whereas other functions in my code generate 800,000+ rows without incident.
The only real unique attribute in this module is that I am using resize a lot (about 100 times per function call), and that the function uses recursive loops during the resize operation (the function is allocating square feet out of a building one tenant at a time, and then updating the remaining feet to be allocated after each tenant lease size and duration is simulated, until all square feet are allocated). Also, the error is happening at nearly the same place each time (but not the exact same location because I have a random number generator that is throwing in some variation to the outcomes). What really confounds me is that the first ~34 calls to this function work fine, and the ~35 call does not require more memory than the previous 34, yet I am having these bad_alloc exceptions on the 35th call nonetheless...
I know it's difficult to help without code. Please just try to give me some direction. My specific questions are as follows:
If I am not using "new" and "delete", and all of my variables are being initialized INSIDE of local functions, is it possible to have memory leaks / allocation problems through repeated function calls? Is there anything I can or should do to manage memory when initializing variables include of local function using "vector Instance;" to declare my variables?
Is there any chance I am running low on stack memory, if I am doing the whole program through the stack? Is it possible I need to load some of my big lookup tables (maps, etc.) on the heap and then just use the stack for my iterations where speed is important?
Is there a problem with using resize a lot related to memory? Could this be an instance where I should use "new" and "delete" (I've been warned in many instances not to use those unless there is a very strong, specific reason to do so)?
[Related to 3] Within the problem function, I am creating a class variable, then writing over that variable about 20 times (once for each "iteration" of my model). I don't need the data from the previous iteration when I do this...so I could ostensibly create a new instance of the variable for each iteration, but I don't understand how this would help necessarily (since clearly I am able to do all 20 iterations on one instance on the first ~34 data slices)
Any thoughts would be appreciated. I can try to post some code, but I already tried that once and everyone seemed to get distracted by the fact that it wasn't compilable. I can post the function in question but it doesn't compile by itself.
Here is the class that is causing the problem:
// Class definition
class SpaceBlockRentRoll
{
public:
double RBA;
string Tenant;
int TenantNumber;
double DefaultTenantPD;
int StartMonth;
int EndMonth;
int RentPSF;
vector<double> OccupancyVector;
vector<double> RentVector;
};
// Class variable declaration (occuring inside function)
vector<SpaceBlockRentRoll> RentRoll;
Also, here is a snippet from the function where the recursion occurs
for (int s=1; s<=NumofPaths; ++s) {
TenantCounter = 0;
RemainingTenantSF = t1SF;
if (RemainingTenantSF > 0) {
while (RemainingTenantSF > 0) {
TenantCounter = TenantCounter + 1;
// Resize relevant RentRoll vectors
ResizeRentRoll(TenantCounter, NumofPaths, NumofPeriods, RentRoll);
// Assign values for current tenant
RentRoll[TenantCounter] = AssignRentRollValues(MP, RR)
// Update the square feet yet to be allocated
RemainingTenantSF = RemainingTenantSF - RentRoll[TenantCounter].RBA;
}
}
}
bad_alloc comes from heap problems of some kind, and can be thrown by any code that indirectly allocates or frees heap memory, which includes all the standard library collections (std::vector, std::map, etc) as well as std::string.
If your programs do not use a lot of heap memory (so they're not running out of heap), bad_allocs are likely caused by heap corruption, which is generally caused by using dangling pointers into the heap.
You mention that your code does a lot of resize operations -- resize on most collections will invalidate all iterators on the collection, so if you reuse any iterator after a resize, that may cause heap corruption that manifests bad_alloc exceptions. If you use unchecked vector element accesses (std::vector::operator[]), and your indexes are out of range, that can cause heap corruption as well.
The best way to track down heap corruption and memory errors in general is to use a heap debugger such as valgrind
Classes like std::vector and std::string are allowed to throw bad_alloc or other exceptions. After all, they have to use some memory that comes from somewhere, and any computer only has so much memory to go around.
Standard 17.6.5.12/4:
Destructor operations defined in the C++ standard library shall not throw exceptions. Every destructor in the C++ standard library shall behave as if it had a non-throwing exception specification. Any other functions defined in the C++ standard library that do not have an exception-specification may throw implementation-defined exceptions unless otherwise specified. [Footnote 1] An implementation may strengthen this implicit exception-specification by adding an explicit one.
Footnote 1: In particular, they can report a failure to allocate storage by throwing an exception of type bad_alloc, or a class derived from bad_alloc (18.6.2.1). Library implementations should report errors by throwing exceptions of or derived from the standard exception classes (18.6.2.1, 18.8, 19.2).
If I am not using "new" and "delete", and all of my variables are being initialized INSIDE of local functions, is it possible to have memory leaks / allocation problems through repeated function calls?
Unclear. If all the variables you refer to are local, no. If you're using malloc(), calloc(), and free(), yes.
Is there any chance I am running low on stack memory, if I am doing the whole program through the stack?
Not if you get bad_alloc. If you got a 'stack overflow' error, yes.
Is it possible I need to load some of my big lookup tables (maps, etc.) on the heap and then just use the stack for my iterations where speed is important?
Well, it's hard to believe that you need a local copy of a lookup table in every stack frame of a recursive method.
Is there a problem with using resize a lot related to memory?
Of course. You can run out.
Could this be an instance where I should use "new" and "delete"
Impossible today without knowing more about your data structures.
(I've been warned in many instances not to use those unless there is a very strong, specific reason to do so)?
By whom? Why?
Within the problem function, I am creating a class variable,
You are creating an instance of the class on the stack. I think. Please clarify.
then writing over that variable about 20 times (once for each "iteration" of my model).
With an assignment? Does the class have an assignment operator? Is it correct? Does the class itself use heap memory? Is it correctly allocated and deleted on construction, destruction, and assignment?
Since, as you said, you are using std::vector with default allocator, problem occurs when you use a lot of std::vector::resize(...) and it occurs after some iterations, my guess is that you run into heap fragmentation problem.
Related
Please see following code,
class MyClass
{
public:
int i;
MyClass()
{
i = 10;
}
};
MyClass* pObj = nullptr;
int main()
{
{
MyClass obj;
pObj = &obj;
}
while (1)
{
cout << pObj->i; //pObj is dangling pointer, still no crash.
Sleep(1000);
}
return 0;
}
obj will die once it comes out of scope. But I tested in VS 2017, I see no crash even after I use it.
Is it good practice to reset int member varialbe i?
Accessing a member after an object got destroyed is undefined behavior. It may seem like a good to set members in a destructor to a predictable and most likely unexpected value, e.g., a rather large value or a value with specific bit pattern making it easy to recognize the value in a debugger.
However, this idea is flawed and dwarved by the system:
All classes would need to play along and instead of concentrating on creating correct code developers would spent time (both development time as well as run-time) making pointless change.
Compilers happen get rather smart and can detect that changes in destructor are not needed. Since a correct program cannot detect whether the change was made they may not make the change at all. This effect is an actual issue for security applications where, e.g., a password should be erased from memory so it cannot be read (using some non-portable mean).
Even if the value gets set to a specific value, memory gets reused and the values get overwritten. Especially with objects on the stack it is most likely that the memory is used for something else before you see the bad value in a debugger.
Even when resetting values you would necessarily see a "crash": a crash is caused by something being setup to protect against something invalid. In your example you are accessing an int on the stack: the stack will remain accessible from a CPU point of view and at best you'd get an unexpected value. Use of unusual pointer values typically leads to a crash because the memory management system tries to access a location which isn't mapped but even that isn't guaranteed: on a busy 32 bit system pretty much all memory may be in use. That is, trying to rely on undefined behavior being detect is also futile.
Correspondingly, it is much better to use good coding practices which avoid dangling references right away and concentrate on using these. For example, I'm always initializing members in the member initializer list, even in the rare cases they end up getting changed in the body of the constructor (i.e., you'd write your constructor as MyClass(): i() {}).
As a debugging tool it may be reasonable to replace the allocation functions (ideally the allocator object but potentially the global operator new()/operator delete() and family with a version which doesn't quickly hand out released memory and instead fills the released memory with a predictable pattern. Since these actions slow down the program you'd only use this code in a debug build but it is relatively simple to implement once and easy to enable/disable centrally it may be worth the effort. In practice I don't think even such a system pays off as use of managed pointers and proper design of ownership and lifetime avoid most errors due to dangling references.
The behaviour of code you gave is undefined. Partial case of undefined behaviour is working as expected, so here is nothing strange that the code works. Code can work now and it can broke anyway at any time depending of compiler version, compiler options, stack content and a moon phase.
So first and most important is to avoid dangling pointers (and all other kinds of undefined behaviour) everywhere.
What about clearing variables in destructor, I found a best practice:
Follow coding rules saving me from mistakes of access to unallocated or destroyed objects. I cannot describe it in a few words but rules are pretty common (see here and anywhere).
Analyze code by humans (code review) or by statical analyzers (like cppcheck or PVS-Studio or another) to avoid cases similar to one you described above.
Do not call delete manually, better use scoped_ptr or similar object lifetime managers. When delete is reasonable, I usually (usually) set pointer to nullptr after deletion to keep myself from mistakes.
Use pointers as rare as it possible. References are preferred.
When objects of my class used outside and I suspect that somebody can access it after deletion I can put signature field inside, set it to something like 0xDEAD in destructor and check at enter or every public method. Here be careful to not slow down your code to unacceptable speed.
After all of this setting i from your example to 0 or -1 is redundant. As for me it's not a thing you should focus your attention.
I am trying to create an array of a object Cell in main function,
int nc=26 730 899;
Cell c[nc];
and Cell is a object which I am constructing with no arguments in.
// Constructor
Cell::Cell(){};
when nc is relatively low it works fine. The problem is when it takes big numbers, like the one in example, where it compiles, but retrieves a bad access error.
Does it mean my computer has no further memory, what kind of memory is this and how can work around this issue?
I am trying to develop a program to run computational fluid dynamics problems using finite volumes method, where each cell is an object so I will need tones of cells!
In the example (3D) I am just trying 299 cells in x by 299 in y by 299 in z = 26 730 899, which is very short yet.
Maybe my approach is being performed the wrong way!?
I am completely new to c++, so keep it as simple as possible, pleaseee. :)
Thank you all.
Note:
I don't know if is it relevant, but I am running the code in Xcode on a MacBookPro from 2010.
Does it mean my computer has no further memory,
Your compiler, unless told otherwise, produces executable programs in which the total size of objects with what the C++ language calls automatic storage duration is limited in a way that makes sense for the operating system on which the program should run.
You haven't shown your full code, but your array apparently has automatic storage duration.
Now, C++ automatic storage duration is usually implemented with something called the stack. How that stack works, how it is limited and how you can change those limits for your program is all implementation-specific.
What matters here is that you just shouldn't create huge objects with automatic storage duration. It's not made for that purpose.
and how can work around this issue?
Use dynamic storage duration and put the objects on the free store with std::vector:
int nc = 26730899;
std::vector<Cell> c(nc);
[*] Your code is also using a non-portable GCC extension, because in standard C++, an array's size must be fixed at compile time, but that doesn't matter much for the problem at hand; you'd probably get the same error if nc was const.
I'm very new to C++ so I'm somewhat confused about how static arrays work. I know in C# the array isn't placed into memory until it's first accessed which can be problematic if you want it to be instantly accessible. However, I'm working on converting a Perlin class to C++ and I'd like to have multiple static arrays of which only one may be used during runtime or any number of them. In reality, it's not really that big of a memory issue as none of them will be more than 50kb, however, I'd rather know if it's possible to ensure the array isn't loaded into memory unless I ask for it. Is there a way to ensure a static array defined in source code isn't loaded into memory unless asked for? It's a pretty nitpicky thing (esp w/ x64), but I'd prefer to be as optimized about it as possible. I hate the idea of taking up memory with something that isn't going to be used.
Or maybe static arrays aren't even the way to go - just dynamical class object wrapped arrays?
I guess the real question is: what is the most efficient solution for implementing table-lookups in c++ that might not all be used?
Static arrays will be in your memory space, with no way to omit or free them, but that is not the same thing as 'in memory'. Leave it up to Windows virtual memory manager. When you first access an array Windows will bring it from disk into RAM.
No, you cannot do that: statically initialized structures and arrays in C++ are loaded into memory along with the rest of your code, so you cannot influence the time at which it gets loaded.
If you must load your static array at runtime, consider changing your strategy to placing the data into a separate file, and adding an initialization function to read the file into a static vector object. This strategy results in placing the data into the dynamic memory area, while the vector object itself could remain static.
Both Windows and Linux uses "demand loading", which means that code and data is loaded when the code reaching it actually needs the data. So assuming the data is constant and global (e.g. static const int x[number] = { ... }), the data will not be loaded. [The typical granularity for this is 4KB or some multiple thereof, but if you have, say, several hundred 50KB blocks of data that aren't being used, you should not see them in memory, and thus no delay in loading the program itself].
As always when it comes to performance and optimisations, it's best to NOT overcomplicate things by trying to predict problems in an area (aka "premature optimisation"), and make sure that what you think MAY be a problem actually is a problem before you optimise it.
I've been trying to deal with low memory situation in my VC++ code.
I've used std::nothrow and checking returns value of new operator for NULL. Application works fine.
But problem is at very low system memory and it crashes abruptly anywhere especially inside STL containers calls (map, vector, queue etc) and the error is "Exception bad_alloc". Obviously these containers cannot allocate required memory so they simply throw bad_alloc.
Now since I've used these containers liberally in my code, I just don't want each and every function inside "try...catch" block. It would clutter the code. (And moreover, the code uses event based library. So, many of the functions are callbacks. Hence, its not like one or few parent caller function(s) I can put in try/catch block and solve this problem)
Without using try/catch, how can this problem be addressed?
At least can someone please tell which of these containers and methods throw bad_alloc (So that I will try putting only that particular code in try/catch block)
If you're not using dynamic_cast or any other features that that it gives you, you can turn off RTTI - that might save you a bit, but probably not enough.
The only other option I can offer is to profile your memory usage, and optimize your code so that you're freeing things you no longer need earlier.
You ask: "how can this problem be addressed?"
Well, what is the problem?
"I don't have enough memory to run my program" — procure more
"My program uses too much memory" — use less
You can't magically work around it any other way.
Does anybody know a "technique" to discover memory leaks caused by smart pointers? I am currently working on a large project written in C++ that heavily uses smart pointers with reference counting. Obviously we have some memory leaks caused by smart pointers, that are still referenced somewhere in the code, so that their memory does not get free'd. It's very hard to find the line of code with the "needless" reference, that causes the corresponding object not to be free'd (although it's not of use any longer).
I found some advice in the web, that proposed to collect call stacks of the increment/decrement operations of the reference counter. This gives me a good hint, which piece of code has caused the reference counter to get increased or decreased.
But what I need is some kind of algorithm that groups the corresponding "increase/decrease call stacks" together. After removing these pairs of call stacks, I hopefully have (at least) one "increase call stack" left over, that shows me the piece of code with the "needless" reference, that caused the corresponding object not to be freed. Now it will be no big deal to fix the leak!
But has anybody an idea for an "algorithm" that does the grouping?
Development takes place under Windows XP.
(I hope someone understood, what I tried to explain ...)
EDIt: I am talking about leaks caused by circular references.
Note that one source of leaks with reference-counting smart pointers are pointers with circular dependancies. For example, A have a smart pointer to B, and B have a smart pointer to A. Neither A nor B will be destroyed. You will have to find, and then break the dependancies.
If possible, use boost smart pointers, and use shared_ptr for pointers which are supposed to be owners of the data, and weak_ptr for pointers not supposed to call delete.
The way I do it is simply:
- on every AddRef() record call-stack,
- matching Release() removes it.
This way at the end of the program I'm left with AddRefs() without maching Releases. No need to match pairs,
If you can reproduce the leak in a deterministic way, a simple technique I often used is to number all your smart pointers in their order of construction (use a static counter in the constructor), and report this ID together with the leak. Then run the program again, and trigger a DebugBreak() when the smart pointer with the same ID gets constructed.
You should also consider this great tool : http://www.codeproject.com/KB/applications/visualleakdetector.aspx
To detect reference cycles you need to have a graph of all reference-counted objects. Such a graph is not easy to construct, but it can be done.
Create a global set<CRefCounted*> to register living reference-counted objects. This is easier if you have common AddRef() implementation - just add this pointer to the set when object's reference count goes from 0 to 1. Similarly, in Release() remove object from the set when it's reference count goes from 1 to 0.
Next, provide some way to get the set of referenced objects from each CRefCounted*. It could be a virtual set<CRefCounted*> CRefCounted::get_children() or whatever suits you. Now you have a way to walk the graph.
Finally, implement your favorite algorithm for cycle detection in a directed graph. Start the program, create some cycles and run cycle detector. Enjoy! :)
What I do is wrap the smart pointer with a class that takes FUNCTION and LINE parameters. Increment a count for that function and line every time the constructor is called, and decrement the count every time the destructor is called. then, write a function that dumps the function/line/count information. That tells you where all of your references were created
What I have done to solve this is to override the malloc/new & free/delete operators such that they keep track in a data structure as much as possible about the operation you are performing.
For example, when overriding malloc/new, You can create a record of the caller's address, the amount of bytes requested, the assigned pointer value returned and a sequence ID so all your records can be sequenced (I do not know if you deal with threads but you need to take that into account, too).
When writing the free/delete routines, I also keep track of the caller's address and the pointer info. Then I look backwards into the list and try to match the malloc/new counterpart using the pointer as my key. If I don't find it, raise a red flag.
If you can afford it, you can embed in your data the sequence ID to be absolutely sure who and when allocation call was made. The key here is to uniquely identify each transaction pair as much as we can.
Then you will have a third routine displaying your memory allocations/deallocation history, along with the functions invoking each transaction. (this can be accomplished by parsing the symbolic map out of your linker). You will know how much memory you will have allocated at any time and who did it.
If you don't have enough resources to perform these transactions (my typical case for 8-bit microcontrollers), you can output the same information via a serial or TCP link to another machine with enough resources.
It's not a matter of finding a leak. In case of smart-pointers it'll most probably direct to some generic place like CreateObject(), which is being called thousands of time. It's a matter of determining what place in the code didnt call Release() on ref-counted object.
Since you said that you're using Windows, you may be able to take advantage of Microsoft's user-mode dump heap utility, UMDH, which comes with the Debugging Tools for Windows. UMDH makes snapshots of your application's memory usage, recording the stack used for each allocation, and lets you compare multiple snapshots to see which calls to the allocator "leaked" memory. It also translates the stack traces to symbols for you using dbghelp.dll.
There's also another Microsoft tool called "LeakDiag" that supports more memory allocators than UMDH, but it's a bit more difficult to find and doesn't seem to be actively maintained. The latest version is at least five years old, if I recall correctly.
If I were you I would take the log and write a quick script to do something like the following (mine is in Ruby):
def allocation?(line)
# determine if this line is a log line indicating allocation/deallocation
end
def unique_stack(line)
# return a string that is equal for pairs of allocation/deallocation
end
allocations = []
file = File.new "the-log.log"
file.each_line { |line|
# custom function to determine if line is an alloc/dealloc
if allocation? line
# custom function to get unique stack trace where the return value
# is the same for a alloc and dealloc
allocations[allocations.length] = unique_stack line
end
}
allocations.sort!
# go through and remove pairs of allocations that equal,
# ideally 1 will be remaining....
index = 0
while index < allocations.size - 1
if allocations[index] == allocations[index + 1]
allocations.delete_at index
else
index = index + 1
end
end
allocations.each { |line|
puts line
}
This basically goes through the log and captures each allocation/deallocation and stores a unique value for each pair, then sort it and remove pairs that match, see what's left.
Update: Sorry for all the intermediary edits (I accidentally posted before I was done)
For Windows, check out:
MFC Memory Leak Detection
I am a big fan of Google's Heapchecker -- it will not catch all leaks, but it gets most of them. (Tip: Link it into all your unittests.)
First step could be to know what class is leaking.
Once you know it, you can find who is increasing the reference:
1. put a breakpoint on the constructor of class that is wrapped by shared_ptr.
2. step in with debugger inside shared_ptr when its increasing the reference count: look at variable pn->pi_->use_count_
Take the address of that variable by evaluating expression (something like this: &this->pn->pi_.use_count_), you will get an address
3. In visual studio debugger, go to Debug->New Breakpoint->New Data Breakpoint...
Enter the address of the variable
4. Run the program. Your program will stop every time when some point in the code is increasing and decreasing the reference counter.
Then you need to check if those are matching.