how to free memory after ASSERT_TRUE in gtest - c++

I have use case scenario.
List* pList = new List();
for (...)
{
Integer* pInt = new Integer();
ASSERT_TRUE(pInt != NULL);
pList->Add(*pInt);
}
Now, should pInt be null in any of iteration, then this test case will stop and pList will not be freed.
Is there any way to free up pList when ASSERT_TRUE executes?
Thanks

If you can use lambdas, you could do:
ASSERT_TRUE(pInt != nullptr)
<< [pList]()->std::string { delete pList; return "Your error message."; }();
The lambda is only executed if the assertion fails.
However, the best option is probably to use a std::unique_ptr or similar smart pointer rather than raw pointers and avoid the worry altogether.

Now, should pInt be null in any of iteration, then this test case will stop and pList will not be freed.
Assuming you didn't override the new operator (if you did, you probably wouldn't be asking about this), and assuming your compiler is not buggy, pInt will never be null. On failure, new throws a std::bad_alloc exception, it doesn't return null.
Moreover, assertions are for things that should always hold (as is the case), no matter what. An assertion failure is a bug. There's no point in adding code to clean up after an assertion failure: just fix the bug instead.
Now to the freeing... The sample code provided can just forget new and use automatic objects:
List pList;
for (...)
{
Integer pInt = Integer();
pList.Add(pInt);
}

Related

What is the difference between returning new object immediately?

What is the difference between these two:
try
{
MyClass* tmp=new MyClass;
return tmp
}
catch (...)
{
cout << "Error";
}
and
try
{
return new MyClass;
}
catch (...)
{
cout << "Error";
}
I think that if an error happened in the second one it will return immediately and not catch the error, right?
They do exactly the same thing.
And will (most likely) generate exactly the same code.
The first one though is helpful if you are using an interactive debugger. After the new is complete it is easier to just check the object (by click on tmp (or typing print tmp into the debug console)) and see if was initialized correctly.
Not something you do often but it comes up.
The two pieces of code will accomplish the same thing. The first one will more easily allow you to see the value of tmp in a debugger or add a line to print its value while debugging.
Unrelated to your question: why are you using new? It is generally better to use std::unique_ptr and std::make_unique instead of a raw pointer and new. std::unique_ptr will also refer to a dynamically allocated instance of MyClass, but will automatically call delete when it goes out of scope, making it less likely for you to have memory leaks in your program.
Both have same functions.
For the try{ } and catch(...) will also work fine in case there are error during allocating memory for MyClass.
But I personally prefer the new method, as sometimes I will do something before return the class.

C++ Memory allocation with operator new: What are the methods of detecting and processing allocation errors?

In previous programs I have used the following code to check for memory allocation failures, usually without thinking about alternatives:
int* p_int = new int[10];
if(!p_int)
{
// We failed, so exit
return EXIT_FAILURE;
}
This method is also documented here.
I found here a reference for the syntax:
p_int = (nothrow) new int[10];
Which suggests that if the programmer does not include the nothrow "argument" to new, then the check for nullptr is invalid? Is this correct? Or is it OS dependent?
As I understand it, there is little point putting new in a try-catch block unless you can actually recover from it because of the overhead associated with this. Is this also correct?
Checking for nullptr after a new is useless because a failed new does not set the pointer to nullptr
int* p_int = new int[10];
if(!p_int)
{
// error handling
}
Rather a failed new will throw a std::bad_alloc, so if you want to try to deal with it, you need to try and catch
try
{
int* p_int = new int[10];
}
catch (const std::bad_alloc& e)
{
std::cout << "Allocation failed: " << e.what();
// deal with it
}
Yes, unless a no-throw version of new was used (and it was not overloaded to do something else!) it will never return null, and instead will throw an exception.
And as for omnipresent check for null when dealing with pointers, this is usually a misguided thing. At most, it should be limited to debug builds. Since null pointers are just a narrow subclass of generally bad (non-dereferenceable) pointers, and they seldom appear in non-debug builds, checking for nulls is just CPU warm-up. For instance, library functions usually do not check their inputs for nulls.

VS 2010 C++ Crash when deleting an array of structures

I have a class with a member function mBoundingBox made up of the following struct
typedef struct
{
unsigned int xMin;
unsigned int yMin;
unsigned int xMax;
unsigned int yMax;
} boundingBox;
class CImgProc
{
public:
CImgProc(void);
virtual ~CImgProc(void);
...
boundingBox *mBoundingBox;
...
}
In code I allocate the member:
mBoundingBox = new boundingBox [mBlobCnt];
piddle around with it (don't assign any pointers to it, just using array indexing), then, when I exit I:
if (mBoundingBox != NULL) delete [] mBoundingBox;
and this is causing an error.
Any input?
Updated info. The error does occur at termination in the destructor. The message generated by VS is:
Windows has triggered a breakpoint in ProcImage.exe.
This may be due to a corruption of the heap, ...
This may also be due to the user pressing F12 while ProcImage.exe has focus.
The output window may have more diagnostic information.
I am setting the pointer to NULL in the constructor and then allocating (with new) when I need to. The pointer is valid, but apparently not on the heap (break lands in dbgheap.c).
Once I allocate the memory, I don't happen to do any pointer magic with it. In this case I am looping through an image and gather stats. Then I use the stats stored in this memory to draw back into my image, but, again, in a rather brute force manner, so nothing else makes use of this memory.
It is legal for me to use new to create an array of structs isn't it?
Doh!!! Sorry to waste ya'lls time. I dug back in and discovered that my creation and destruction are fine, but somewhere in the middle I set the value of mBoundingBox[X]. whatever where it turns out X is the dim of the array created.
Typical user error, just a surprising place for the bug to show up.
Most probably you are deleting your array twice. To manage it better use
delete[] mBoundingBox;
mBoundingBox = 0;
instead of
if (mBoundingBox != NULL) delete [] mBoundingBox;
or even better use a smart pointer.
first of all the following check is wrong
if (mBoundingBox != NULL) delete [] mBoundingBox;
new does not returns NULL when it fails to allocate memory, rather it throws an exception.
use nothrow version of "new" if you want to proceed like you are doing. In nothrow version new will return NULL instead of throwing an exception.
mBoundingBox = new (std::nothrow) boundingBox [mBlobCnt];

(not) using std::string in exceptions

I'm always reading that I should not to throw a std::string or some other classes allocating memory. like here or more importantly here on point 3. - Don't embed a std::string object.
So now I'm trying to insert boost::exception to my project and what do I see: lots of strings.
Why doesn't boost comply with its own recommendation?
And if I have parameters which can't be hardcoded, like safed in an config-file, how can I put them into an exception, without using std::string?
Or is the guideline don't use std::string only a do use std::string as seldom as possible guideline? I'm a bit confused...
I've done some research. Please correct me if i'm wrong.
If I understand it right, it's all about the allocation during the throw and what is happening to the allocated memory. So the memory gets lost if I allocate it in the constructor and it can't be freed in the destructor of the exception, that will produce a memory-leak. But it's okay to allocate this before throwing, so the exception is clean.
I tried this:
struct xexception {
int *ttt[10];
xexception() {
ttt[0] = new int[0xfffffffL];
ttt[1] = new int[0xfffffffL];
ttt[2] = new int[0xfffffffL];
ttt[3] = new int[0xfffffffL];
ttt[4] = new int[0xfffffffL];
ttt[5] = new int[0xfffffffL];
ttt[6] = new int[0xfffffffL];
ttt[7] = new int[0xfffffffL];
ttt[8] = new int[0xfffffffL];
ttt[9] = new int[0xfffffffL];
}
~xexception() throw() {
//never happen
delete[] ttt[0];
delete[] ttt[1];
delete[] ttt[2];
delete[] ttt[3];
delete[] ttt[4];
delete[] ttt[5];
delete[] ttt[6];
delete[] ttt[7];
delete[] ttt[8];
delete[] ttt[9];
}
};
int main(int argc, const char *argv[]) {
try {
throw(xexception());
}
catch (const xexception &e) {
std::cerr << "\nttt " << e.ttt[0][0] << std::endl;
}
catch (std::bad_alloc) {
std::cerr << "bad alloc" << std::endl;
}
return 0;
}
The result is, I get the bad_alloc and a huge memory leak.
Now if I do the allocation before, it also throws the bad_alloc but before the exception is created.
My exception to the exception concept is:
Who cares? If I have a bad_alloc in my program, because of a memory_leak or something else (I'm talking about programs on PCs not microcontrollers) I have other problems. Maybe I can figure out that a bad_alloc happened, but where? On my alloc during a function (one of maybe 1000) or in the std::string (well I know it's the string but ... no possibility to manipulate the memory of the string... or its to dissipated).
try {
// where is the error???
int *x = new int[100]; // here?
....
int *y = new int[100]; // or here?
....
int *z = new int[100];
....
int *w = new int[100];
....
int *t = new int[100];
....
int *f = new int[100];
....
std::string str("asdfasdfasdfasdfasdfasdfasdf"); // maybe here
}
catch (the error) {
....
}
And then? Shall I try to figure out where it's happening? Therefore I would use valgrind not exceptions.
void foo() {
int *i = new int[1];
foo();
}
try {
foo();
}
chatch( bad_boy ) {
go_exception_handler_go(parameters); // oh, shit happens: also an stack_overflow may happend, cause stack is also full
}
Or shall i manipulate the errormessage and log it, what definitively would throw the next bad_alloc.
Please don't misunderstand me. Since I've seen the boost::exception I've rewritten my exception class (till waiting on an answer) but I also think it is not really necessary to pick up every grain of sand.
The advice is basically telling you "Don't use any construct that might throw an exception in an exception". That's because if you get an exception while trying to throw an exception, the C++ runtime will just immediately call terminate() and kill your program.
Now if (either) of the exceptions involved would just call terminate() anyways (as is the default for an uncaught exception), then you don't really need to worry about it. For example, if your application can't handle bad_alloc (can't recover from out-of-memory), then you don't need to worry about copy constructors (such as std::string) that might throw it.
But if you want to be able to catch and recover from a bad_alloc, you need to ensure that none of your exception copy constructors can cause one. If you're writing a library that other applications will use, you should not assume that the application does not want to handle bad_alloc.
C++11 make this much easier by using move constructors (instead of copy constructors) where possible. Since the move constructor for std::string never throws exceptions you can safely use a std:string in your exception type as long as you properly implement move constructors, and ensure that they are used. Note that the initial construction of the object to be thrown in a throw expression is NOT part of the exception throwing process, so that constructor can throw an exception without causing a double exception (and terminate()). So if you have:
throw some_function();
some_function might throw an exception (such as bad_alloc) without returning an object to be thrown and that's fine. If it doesn't throw an exception (and returns a valid object), the move constructor for the exception type will be used (if available) for the exception throwing process, and that move constructor must not throw an exception.
Completely independent of the above, whenever you call new you need to ensure that exactly one spot will call delete in every possible case, or you'll leak memory (or crash from a double delete). This becomes tricky any time you have a function that calls new and then does something else that might throw an exception (such as call new again). If this happens in a constructor, the destructor for the object will not be called (though destructors for base classes and fields will be), so you can't do the cleanup in the destructor as you are trying to do with your example.
Fortunately std::unique_ptr exists to make this much easier. If you write your exception class as:
struct xexception {
std::unique_ptr<int[]> ttt[10];
xexception() {
ttt[0].reset(new int[0xfffffffL]);
ttt[1].reset(new int[0xfffffffL]);
ttt[2].reset(new int[0xfffffffL]);
ttt[3].reset(new int[0xfffffffL]);
ttt[4].reset(new int[0xfffffffL]);
ttt[5].reset(new int[0xfffffffL]);
ttt[6].reset(new int[0xfffffffL]);
ttt[7].reset(new int[0xfffffffL]);
ttt[8].reset(new int[0xfffffffL]);
ttt[9].reset(new int[0xfffffffL]);
}
};
it should work and not leak memory.
While I think not using std::string for core, fundamental exceptions may be a good guideline, I don't think user-facing libraries/applications should necessarily follow this.
There may be other reasons, but you hit on the primary one: you'd like to indicate to the user (or developer) contextually meaningful information, which you often cannot do with a mere literal string. A dynamic allocation must occur in order to do this. If, for some reason, you had a bad_alloc, you're probably already hosed to begin with, so it doesn't buy/lose you anything.
Edit:
By the way: the destructor of std::exception is marked as virtual for a reason!

Confusion on C++ programming practise with exception handling

I have a C++ code mentioned below:
#include<iostream>
#include<stdexcept>
const long MAX = 10240000;
class Widget{
public:
Widget(){
ok = new int [1024];
prob = new int [100*MAX];
}
~Widget(){
std::cout<<"\nDtoR of Widget is called\n";
delete ok; ok = NULL;
delete prob; prob = NULL;
}
//keeping below public: Intentionally
int* ok;
int* prob;
};
void func(){
Widget* pw = NULL; // <<<<--------------- Issue in Here
try{
pw = new Widget;
}
catch(...){
delete pw;
std::cout<<"\nIn catch BLOCK\n";
if(pw->ok == NULL){
std::cout<<"\n OK is NULL\n";
}
throw;
}
delete pw;
}
int main(){
try{
func();
}
catch(std::bad_alloc&){
std::cout<<"\nError allocating memory."<<std::endl;
}
std::cout<<std::endl;
system("pause");
return 0;
}
Now in function func(), i am seeing two different behavior depending on if i do not set pointer 'pw' to NULL and if i do set 'pw' pointer to NULL (like code above). I was under the impression that it is 'good' practise to first set pointer to NULL and then initialize it. But when i initilize it to NULL then the output just shows "In catch BLOCK" and later app crashes. but if i do not set pw pointer to NULL, then i see destructor of pw is called and following output is shown w/o any app crash.
DtoR of Widget is called
In catch BLOCK
OK is NULL
Error allocating memory.
Press any key to continue . . .
My question is why such difference in one case when we are not initializing 'pw' pointer to NULL and in other case we are setting it to NULL. Why destructor is called in one case and why it was not called in another.
Note: The intent of this code is to throw bad_alloc exeption.
If you do not set pw to NULL then you will leave it uninitialized. Then, when new operator inside a "try" block throws an exception, it never returns, and you get into catch block. Since new never returned, pw will still be not initialized, and you will pass a random address to delete. That gives you an undefined behavior.
In your catch block, you have:
if(pw->ok == NULL)
At this point, pw is NULL (or garbage, in the case that you didn't initialise it). pw-ok attempts to dereference it, giving undefined behaviour (a crash in this case).
If you didn't initialise it, then the delete pw will crash before printing the "catch" message; most likely, it will print the "Dtor" message before crashing, but there is no guarantee since you're firmly in the realm of undefined behaviour.
If you did initialise it, then delete pw is unnecessary but harmless; deleting a null pointer is defined to do nothing. So in that case you won't crash until you dereference it.
In any event, you have an unfixable memory leak - the first allocation ok = new int[1024] will have succeeded, but you have lost the only pointer to it. This is why you should always manage dynamic memory using smart pointers, containers, and other RAII techniques.
you are going to intend the bad_alloc exeption.but you have more unhandled exceptions!
It is not ok to delete pw first and then using the pointer of it!
delete pw;
if(pw->ok == NULL)
Why would you call pw->ok after you delete pw? It's already gone.
You constructor should have member initializes
Widget():ok(NULL), prob(NULL) {
...
}
because if Widget() fails, you don't know which member variable is initialized and which is not which can cause problem in your destructor.
Since you allocated with int[], you need to delete[] not just delete in your destructor.
You are seeing the app crash when you set pw to NULL because of the line
if (pw->ok == NULL)
You are dereferencing NULL which is causing the crash. In the other case you are deleting garbage which will give you undefined behavior.
Also, you should not use a pointer after calling delete on it. That can cause all kinds of weird behavior.
To explain more of what is happening. Your Widget constructor is throwing the allocation exception. In this case most likely the allocation for ok completed, but the allocation for prob failed. Your constructor never finishes, leaking the memory that was allocated to the ok variable. If you want to ensure the memory is cleaned up, you should add a try catch in your constructor.
Widget() : ok(NULL), prob(NULL)
{
try
{
ok = new int [1024];
prob = new int [100*MAX];
}
catch(...)
{
std::cout << "\nCtor of Widget threw exception\n";
delete [] ok;
delete [] prob;
throw;
}
}
It's good to initialize pw to NULL, but when deleting it, you should first check if pw is not null. Something like:
if (pw) delete pw;
Also, if pw is NULL, you can't reference its members.