Throw exception in constructor c++ - c++

I have created a class and I want not to create the object if one member is empty. These are the code lines:
#include "verification/CVerifObj.hpp"
VerifObj::VerifObj(const fs::path& imgNameIn)
{
m_image = cv::imread(imgNameIn.string());
AnalyseCSV csv;
m_plateContour = csv.getPlateRegion(imgNameIn); // search for the csv file and load the values
if (m_plateContour.empty()) // throw exception if empty csv
{
throw EmptyContourException(imgNameIn.string());
}
m_imageName = imgNameIn.string();
}
VerifObj::~VerifObj()
{
// are these enough for destructor?
m_image.release();
m_plateContour.clear();
}
Is this OK, or shall I do something more? How shall I be sure that if the exception is thrown the object is not created?
I have the following lines of code for ensuring it:
for(fs::directory_iterator iter(folderIn); iter != end; ++iter)
{
if(!fs::is_regular_file(iter->status()))
{
continue;
}
std::string extension = iter->path().extension().string();
if(targetExtensions.find(extension) == targetExtensions.end())
{
continue;
}
try
{
VerifObj verifObj(iter->path());
verifObjVecRet.push_back(verifObj);
}
catch (EmptyContourException& ece)
{
continue;
}
catch (CSVException &csve)
{
continue;
}
}

Hopefully, m_image and m_plateContour (and any other non-trivial members of your class) are properly designed RAII types, with destructors that clean up any resources they might have.
In that case, your class won't need a destructor at all, and all the members will be properly destroyed automatically if your constructor throws - there's no need to take any action there.
However, the presence of the destructor implies that they might be evil types which do need manually cleaning up before destruction. In that case, fix them.
If you can't fix them for some reason, you'll need m_image.release(); before throwing. You'll also need a large coffee supply, as classes like that will lead to long debugging sessions trying to fix memory leaks.

The short answer is, throwing stuff in the constructor is dangerous.
First, lets define the design problem: you have a class that can fail to initialize. If the class fails to initialize, it cannot be used (will cause additional errors if used), so the class failing is considered a "critical failure", atleast where the class is concerned.
In a nutshell, what we want to avoid is letting a user use a class that failed to initialize.
Imagine the following situation:
class A
{
public:
A()
{
stuff1 = malloc(100);//some dynamic memory allocation
throw "This throw is crazy";
stuff2 = malloc(100);//some dynamic memory allocation
}
~A() {free(stuff1); free(stuff2);}
private: void* stuff2;void* stuff2;
};
int main(int argc, char** argv)
{
A a;
}
Once you throw in the constructor, what happens to stuff? well, it is an instant memory leak. The destructor is never called. Which is baaaad. If you handle the exception:
int main(int argc, char** argv)
{
try
{
A a;
}
catch(...)
{
//can't do much here
}
}
You've lost the reference to A, which is a nightmare. So some people try to get away with this instead (Up front, it is still bad)
int main(int argc, char** argv)
{
A* a;
try { a= new A();}
catch(...){delete a;}
}
But that is just as bad. You may still have a reference to a (and the memory directly pointed to by a will not leak) but a is now in an unknown state...you'll still have to delete it some day, and the free for stuff2 failed.
One way to get around this is to make your constructor and destructor alot smarter. Catch any exceptions that can be thrown in the constructor, and clean up the object, returning a "zombie" object. And have the destructor easily be able to check for the zombie object. I find this method to be more complicated.
A better way to some is to use an initializer:
class A
{
public:
A() {stuff1=null; stuff2=null;}
void init()
{
stuff1 = malloc(100);//some dynamic memory allocation
throw "This throw is crazy";
stuff2 = malloc(100);//some dynamic memory allocation
}
void destroy() {if (stuff1) {delete stuff1; stuff1=NULL;} if (stuff2) {delete stuff2; stuff2=NULL;}}
~A() {destroy();}
};
I don't like this because you still get "zombie" objects, and have all the added upkeep of calling init and destroy. Going back to the original problem, both a smarter constructor and providing initalizers still don't solve the nutshell statement: the end user can still (pretty easily, in fact) use an instance that is in an unknown state.
I like to follow a pseudo RAII (Resource Acquisition Is Initialization) here: what you want to to ensure that, if you have a reference to an object, it is a valid reference. Else, there should be no memory leaks. The best way (IMHO) to achieve this is to use a factory method, and keep all the initializes private.
class A
{
public:
~A() {destroy();}
static A* MakeA()
{
A* ret = new A();
try { ret->init();}
catch(...)
{
delete ret;
return NULL;
}
return ret;
}
private: void* stuff1,*stuff2;
A() {stuff1=null; stuff2=null;}
void init()
{
stuff1 = malloc(100);//some dynamic memory allocation
throw "This throw is crazy";
stuff2 = malloc(100);//some dynamic memory allocation
}
void destroy() {if (stuff1) {delete stuff1; stuff1=NULL;} if (stuff2) {delete stuff2; stuff2=NULL;}}
};
Now the user can never make a valid reference to a failed object, which is nice.
Protips:
Exception handling is slow. If you expect this to happen often, or don't think that it will be a fatal error, use error codes in your init statements. Error codes in the factory method can give the user more info as well.
I used raw pointers in this answer cuz I'm too lazy to write all those characters in an answer. Always use smart pointers and this becomes even easier. Juggling raw pointers is only for the criminally insane. (CLARIFYING USE SMART POINTERS)
Edit: clarified what I'm lazy about

Related

C++ , how come I do not get the value "123456"

I am trying to print out value 123456, but it gives me the garbage value. How can I fix it? And Can you please explain why it gives the wrong value?
#include <stdio.h>
#include <stdlib.h>
struct MyInfo
{
private:
int private_key = 123456;
public:
int setkey(int value)
{
private_key = value;
}
int GetScore()
{
return private_key;
}
};
void main()
{
MyInfo* pMyInfo;
pMyInfo = (MyInfo*)malloc(sizeof(MyInfo));
printf("%d\n", pMyInfo->GetScore());
free(pMyInfo);
}
Don't use malloc/free but rather pMyInfo = new MyInfo() and delete pMyInfo. Only new will call the constructor which initializes the value; only delete will call the destructor.
Regarding the comment, what is meant is, you can also have it on the stack, i.e. MyInfo pMyInfo;, i.e. not a pointer. That will automatically call the constructor and when it goes out of scope, the destructor.
int private_key = 123456;
This really is just a camouflaged constructor initialization which means it's the same as:
MyInfo() : private_key(123456) {}
Since malloc and friends are inherited from C and C has no classes (and thus no special member functions) whatsoever malloc and friends won't call these necessary special member functions to set up your object. The C++ equivalent new does however which is why you should always use new over malloc and delete over free.
But wait, there's more...
Actually, you shouldn't ever use new either, there are always better alternatives than using raw dynamic allocation. If you really need dynamic memory allocation then use std::unique_ptr or for multiple objects std::vector but most of the time you don't even need these ( there are tons of posts on here that explain when dynamic allocation is a must, for all the other cases just use storage with automatic lifetime) all you need in this case is a local object:
MyInfo myInfo;
printf("%d\n", myInfo.GetScore());
See how your code just got shorter, easier to maintain and cleaner to achieve the same?
When you declare a pointer of type MyInfo, it does not mean that the object it points to will actually be your struct, it just assumes it will be.
When you do malloc(sizeof(MyInfo)), you simply allocate memory of the size which your struct might take, it does not create an object. Hence, when you try to do GetScore(), it accesses memory location which it assumes contains your private_key, but instead it simply contains garbage.
Don't mix C and C++
You should avoid malloc/alloc etc in C++ and opt for new operator if you want to work with dynamically allocated objects.
Add a constructor to initialize the value
private;
int private_key;
public:
MyInfo () {
private_key = 123456;
}
And implement the main like
// without pointer
void main () {
MyInfo myinfo;
printf("%d\n", myinfo.GetScore());
}
// with pointer
void main () {
MyInfo *myinfo = new MyInfo();
printf("%d\n", myinfo->GetScore());
}
Just for reference, it is possible to initialize an object in raw storage, but it would be overkill and rather stupid for this use case. As malloc only allocate raw memory and does not construct an object, you could use a placement new to build the object in a second time:
int main() // I can't stand void main
{
MyInfo* pMyInfo;
pMyInfo = (MyInfo*)malloc(sizeof(MyInfo)); // only allocate raw memory
new((void *) pMyInfo) MyInfo; // construct the object
std::cout << pMyInfo->GetScore() << std::endl; // no reason for C printf here
pMyInfo->~MyInfo(); // placement new requires explicit destructor call if not trivial
free(pMyInfo);
return 0;
}
DO NOT DO THAT for such a simple case. Placement new should only be used in very special cases where the allocation is not trivial, for example when you use share memory. But here the correct way is to simply use an automatic object:
int main() // I can't stand void main
{
MyInfo pMyInfo;
std::cout << pMyInfo.GetScore() << std::endl;
return 0;
}

Using malloc/free to simulate new/delete

I created an example classes (only for learning purposes) which don't have to use constructor initialization lists because I want to get the same effects using new/delete and malloc/free. What are other constraints besides not using constructor initialization list? Do you think that the following code simulate the new/delete behavior in the right way?
#include <iostream>
using namespace std;
class X
{
private:
int* a;
public:
X(int x)
{
this->a = new int;
*(this->a) = x;
}
~X() { delete this->a; }
int getA() { return *(this->a); }
};
class Y
{
private:
int* a;
public:
void CTor(int x)
{
this->a = new int;
*(this->a) = x;
}
void DTor() { delete this->a; }
int getA(){ return *(this->a); }
};
void main()
{
X *xP = new X(44);
cout<<xP->getA()<<endl;
delete xP;
Y *yP = static_cast<Y*>(malloc(sizeof(Y)));
yP->CTor(44);
cout<<yP->getA()<<endl;
yP->DTor();
free(yP);
system("pause");
}
Without using delete xP, destructor will be called automatically when program ends, but a free store won't be freed (i.e. free store for xP, free store for field a will be freed) . When using delete xP destructor is called and then a free store is completely freed.
Please correct me if I'm wrong.
The actual answer to your question is that you are incorrect, not calling delete xP will lead to a memory leak. It is very likely that the OS then cleans up the memory for you, but it's not GUARANTEED by the C++ runtime library that this happens - it's something that OS's generally offer as a nice service [and very handy it is too, since it allows us to write imperfect code and have code that does things like if (condition) { cout << "Oh horror, condition is true, I can't continue" << endl; exit(2); } without having to worry about cleaning everything up when we've got something that went horribly wrong].
My main point, however, is that this sort of stuff gets very messy as soon as you add members that in themselves need destruction, e.g.
class X
{
private:
std::string str;
...
};
There is no trivial way to call the destructor for str. And it gets even worse if you decide to use exceptions and automated cleanup.
There are many subtle differences that distinguish new from malloc and delete from free. I believe they are only equivalent if the class is POD type.
I should warn that you can never mix the two types freely. A new must always be balanced by a delete and never by a free. Similarly malloc must be balanced only by free. Mixing the two results in undefined behaviour.

(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!

Calling delete on automatic objects

Consider the following c++ code:
class test
{
public:
int val;
test():val(0){}
~test()
{
cout << "Destructor called\n";
}
};
int main()
{
test obj;
test *ptr = &obj;
delete ptr;
cout << obj.val << endl;
return 0;
}
I know delete should be called only on dynamically allocated objects but what would happen to obj now ?
Ok I get that we are not supposed to do such a thing, now if i am writing the following implementation of a smart pointer, how can i make sure that such a thing does't happen.
class smart_ptr
{
public:
int *ref;
int *cnt;
smart_ptr(int *ptr)
{
ref = ptr;
cnt = new int(1);
}
smart_ptr& operator=(smart_ptr &smptr)
{
if(this != &smptr)
{
// House keeping
(*cnt)--;
if(*cnt == 0)
{
delete ref;
delete cnt;
ref = 0;
cnt = 0;
}
// Now update
ref = smptr.ref;
cnt = smptr.cnt;
(*cnt)++;
}
return *this;
}
~smart_ptr()
{
(*cnt)--;
if(*cnt == 0)
{
delete ref;
delete cnt;
ref = 0;
cnt = 0;
}
}
};
You've asked two distinct questions in your post. I'll answer them separately.
but what would happen to obj now ?
The behavior of your program is undefined. The C++ standard makes no comment on what happens to obj now. In fact, the standard makes no comment what your program does before the error, either. It simply is not defined.
Perhaps your compiler vendor makes a commitment to what happens, perhaps you can examine the assembly and predict what will happen, but C++, per se, does not define what happens.
Practially speaking1, you will likely get a warning message from your standard library, or you will get a seg fault, or both.
1: Assuming that you are running in either Windows or a UNIX-like system with an MMU. Other rules apply to other compilers and OSes.
how can i make sure that [deleteing a stack variable] doesn't happen.
Never initialize smart_ptr with the address of a stack variable. One way to do that is to document the interface to smart_ptr. Another way is to redefine the interface so that the user never passes a pointer to smart_ptr; make smart_ptr responsible for invoking new.
Your code has undefined behaviour because you used delete on a pointer that was not allocated with new. This means anything could happen and it's impossible to say what would happen to obj.
I would guess that on most platforms your code would crash.
Delete's trying to get access to obj space in memory, but opperation system don't allow to do this and throws (core dumped) exception.
It's undefined what will happen so you can't say much. The best you can do is speculate for particular implementations/compilers.
It's not just undefined behavior, like stated in other answers. This will almost certainly crash.
The first issue is with attempting to free a stack variable.
The second issue will occur upon program termination, when test destructor will be called for obj.

Could you give me a real work example of memory leak?

I heard a lot of memory leak vulnerability, but I could not find a real work example of memory leak, could you provide a real work example of memory leak, maybe of some big open source project and explain the solution to me
thx.
It's really simple actually. In your main put:
char* c = new char[4];
Then exit. That's a memory leak. Any new that doesn't get followed by delete is a leak.
This answer has some good examples, but like my comment has said, it will be fairly hard to find a released application with a leak that an outside observer can look at and easily identify.
I am screaming, cursing and yelling everyday about code like this in our (huge) legacy code base:
// returns raw pointer with changing conventions who's the owner...
HelpFoo* Foo::GetFoo(Bar* pBar, OtherFoo* pFoo)
{
// all 'local' variables even those allocated on freestore declared
// and initialized in a large block at the beginning of the function/method
HelpFoo *A = new HelpFoo;
OtherHelpFoo *B, *C;
EvenMore *D = new EvenMore;
// and so on, these blocks can be huge...
// a complicated spaghetti code in here, with dozens of nested 'ifs'
if (/* some expression */) {
} else if (/* some other expression */) {
// and so on... then suddenly:
if (/* some other nested expression */) {
// I forgot that I've allocated other memory at the beginning...
return A;
}
}
// some miserably written logic here and suddenly
if (D) delete D; return A;
// call to some other function with cryptical name without any
// kind of knowledge what happens with the resource:
FooTakesReferenceToPointer(&A);
// suddenly returning something completely different
// what should I free, A, D...?
return C;
}
I tried to write in comments what the problems are. Clearly, forget about exceptions. The spaghetti code is so bad that nobody can tell what the logic actually is. Therefore it is really, really easy to forget to free memory and that happens very, very frequently. Solution 1: Throw away and rewrite everything. Solution 2: Keep spaghetti as it is, replace all newed resources by smart pointers and make_shared or make_unique, let compiler yell. Of course, first write a test suite (which didn't exist before) to guarantee the same (often screwed) behaviour for all possible sets of inputs (which are not documented).
EDIT
As james said this is undefined behaviourso no promises
You could do something like this:
#include <vector>
class Base
{
public:
Base()
{
baseData = new char [1024];
}
~Base()
{
delete [] baseData;
}
private:
char* baseData;
};
class Derived : public Base
{
public:
Derived()
{
derivedData = new char[1024];
}
~Derived()
{
delete [] derivedData;
}
private:
char* derivedData;
};
int main()
{
std::vector<Base*> datablocks;
datablocks.push_back(new Base());
datablocks.push_back(new Derived());
for(unsigned int i = 0; i < datablocks.size(); ++i)
{
delete datablocks[i];
}
datablocks.clear();
return 0;
}
The data in the Derived class wont be removed here since we are calling delete on a Base* and the Base class does not declare a virtual destructor.
A lot examples could be given here. Just allocate some memory and do not free it.
A good example for this would be the following:
char* pBuffer = new char[ 1024 ]; // or something else, dynamically allocated
// do something here
// now suppose, calling f() throws
f();
// do some other things
delete[] pBuffer;
When f() throws, if the exception is not caught, delete[] will never be executed. Thus, memory leak.
This is one of the best examples why smart pointers should be used.
Another example would be - a function, returning pointer to dynamically allocated memory. The user, often, may forget to free this memory. Something like:
char
char* f()
{
return new char[ 1024 ];
}
//...
// in some other function
char* pSomething = f();
// do some stuff here and return
Imagine you're processing network data and create polymorphic "message objects" based on the data:
while (true)
{
char buf[1024];
size_t len = read_from_network(buf, 1024); // fictitious, for demonstration only
Message * p = Message::Parse(buf, len); // allocates new, dynamic, concrete object
engine.process(p);
}
The engine object may chose to store the object somewhere and use it again later, and if nobody takes care of deleting it, you have a perfect leak.
While the other answers give enough hints, some 'real world' memory leaks which I have seen in our applications.
I don't remember if this was found before or after the release, but, I guess that doesn't matter.
void f()
{
BYTE* b = NULL;
f = open a file;
while (!f.end())
{
int size = getNextRecordSize(f);
b = new BYTE;
readNextRecord(f,b);
process record;
}
delete b;
}
Bit hard to detect this. The reviewers might take it for granted that the memory is deleted properly by seeing the delete call. However, it deletes only the memory allocated for the last record. Rest is leaked.
class A
{
public:
BYTE* get()
{
allocate a new buffer, copy the someData buffer and return that.
The client is expected to delete it
};
private:
BYTE* someData;
};
void f()
{
A a;
B.initialize(a.get()); // It is so convenient to use the pointer. It is not obvious from the function name
// that the result of get has to be deleted.
}
One example I often run across in our code is in image understanding functions, where a temporary 8bit memory is allocated, and never released (yeah, I know, when you do a new, do a delete right afterwards...)
unsigned char* dataToBeUsed = new unsigned char[imgsize];
memcpy(dataToBeUsed, original, imgsize);
// use and process the data here
return value;
The allocated memory is never released -> memory leak. Windows will kill the memory when the application is exited completely, but before that within the application that memory is just lost -> leaked.
A memory leak occurs when the programmer has the memory leak of forgetting to free allocated memory :-)
linebuffer = new char[4096];
/* do things */
/* forget to free memory */
Normally, if you cause a memory leak and then exit the program, it is not harmful, since the operating system normally frees the resources allocated by the program. The problem arises when your application runs for a long period of time (for example, a service). If your program causes memory leaks, then you will run out system's memory, unless the operating system has mechanisms to avoid that; in such case, it will terminate your program.
So, be careful and eat fish: it's very good for memory :-)
To give you a real-world example, a bit of googling turned up this memory leak in 389 Directory Server (a RedHat Open Source product).
Just lose the pointer to dynamically allocated memory:
void foo()
{
int *arr = new int[100];
}