How to copy a non null terminated string to dynamic memory - c++

First off, this is not a duplicate. My question is how to do it with dynamic memory. The reason this is distinct is because my delete[] is hanging.
So, here's what I have:
class PacketStrRet {
public:
PacketStrRet(char p_data[], int p_len) : len(p_len) {
data = new char[p_len];
memcpy(data, p_data, p_len * sizeof(char));
}
~PacketStrRet() {
delete[] data;
data = nullptr;
}
char* data;
int len;
};
And yes, I'm aware that my code is not using the best practices. I'll clean it up later.
The problem I'm having is in the DTOR. That delete is hanging forever. The data being passed in to the CTOR is not dynamic memory, so I need to make it dynamic so things don't go out of scope. p_len holds the correct amount of data, so there's no problem there.
From what I've read, memcpy seems to be the most likely culprit here. So how do I copy a string that is not null-terminated to dynamic memory, and then still be able to delete it later?
Thanks.

The problem is not the delete, only everything that comes before and even that would be ok if there didn't occur any problems.
class PacketStrRet {
// Use RAII
std::unique_ptr<char> data; // I own this data and will destroy it.
// now the parent class is also only movable, use shared_ptr if you can't live with that.
int len;
public:
PacketStrRet(
// <RED ALERT>
char p_data[], int p_len // user can lie to us.
// </RED ALERT>
) try : // function try block, se 1)
len(p_len), data(new char[p_len]) {
memcpy(data, p_data.get(), p_len * sizeof(char));
} catch(const std::exception& e) {
std::cerr << "arg=" << arg << " failed: " << e.what() << '\n';
}
~PacketStrRet() {
// unique_ptr takes care of memory management and garbage collection.
}
// access functions
};
Now the possible errors you could make to blow the code up.
You could have copied the object, essentially making two owning raw pointers to the same data. This would blow up at delete, you coudl use memory-sanitizer / valgrind to confirm this happens. Use smart pointers to save you the trouble, the unique pointer should cause a compiler error if you tried to copy, unless you memcpy the entire structure ignoring the copy/assignment constructors.
You could give the wrong len to the constructor, what is the source of the data and len? Valgrind / memory-sanitizer can save you.
The memory corruption could happen in a totally different place. Valgrind / memory-sanitizer can save you.
In case valgrind mem-san are too much, you can try to make a check for double delete, if you make a counter in c'tor and d'tor and if it ever goes to negative you have your error.
In this class your at least missing a copy constructor. Check up on rule of 3, 5, 7 and 0 (zero) to find out how many you need.
1) http://en.cppreference.com/w/cpp/language/function-try-block

Try to use std:: copy(). It will be like this:
std::copy(p_data, p_data + p_len, data).

Related

how to handle double free crash in c++

Deleting the double pointer is will cause the harmful effect like crash the program and programmer should try to avoid this as its not allowed.
But sometime if anybody doing this then i how do we take care of this.
As delete in C++ is noexcept operator and it'll not throw any exceptions. And its written type is also void. so how do we catch this kind of exceptions.
Below is the code snippet
class myException: public std::runtime_error
{
public:
myException(std::string const& msg):
std::runtime_error(msg)
{
cout<<"inside class \n";
}
};
void main()
{
int* set = new int[100];
cout <<"memory allcated \n";
//use set[]
delete [] set;
cout <<"After delete first \n";
try{
delete [] set;
throw myException("Error while deleting data \n");
}
catch(std::exception &e)
{
cout<<"exception \n";
}
catch(...)
{
cout<<"generic catch \n";
}
cout <<"After delete second \n";
In this case i tried to catch the exception but no success.
Pleas provide your input how we'll take care of these type of scenario.
thanks in advance!!!
Given that the behaviour on a subsequent delete[] is undefined, there's nothing you can do, aside from writing
set = nullptr;
immediately after the first delete[]. This exploits the fact that a deletion of a nullptr is a no-op.
But really, that just encourages programmers to be sloppy.
Segmentation fault or bad memory access or bus errors cannot be caught by exception. Programmers need to manage their own memory correctly as you do not have garbage collection in C/C++.
But you are using C++, no ? Why not make use of RAII ?
Here is what you should strive to do:
Memory ownership - Explicitly via making use of std::unique_ptr or std::shared_ptr and family.
No explicit raw calls to new or delete. Make use of make_unique or make_shared or allocate_shared.
Make use of containers like std::vector or std::array instead of creating dynamic arrays or allocating array on stack resp.
Run your code via valgrind (Memcheck) to make sure there are no memory related issues in your code.
If you are using shared_ptr, you can use a weak_ptr to get access to the underlying pointer without incrementing the reference count. In this case, if the underlying pointer is already deleted, bad_weak_ptr exception gets thrown. This is the only scenario I know of when an exception will be thrown for you to catch when accessing a deleted pointer.
A code must undergo multiple level of testing iterations maybe with different sets of tools before committing.
There is a very important concept in c++ called RAII (Resource Acquisition Is Initialisation).
This concept encapsulates the idea that no object may exist unless it is fully serviceable and internally consistent, and that deleting the object will release any resources it was holding.
For this reason, when allocating memory we use smart pointers:
#include <memory>
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
using namespace std;
// allocate an array into a smart pointer
auto set = std::make_unique<int[]>(100);
cout <<"memory allocated \n";
//use set[]
for (int i = 0 ; i < 100 ; ++i) {
set[i] = i * 2;
}
std::copy(&set[0], &set[100] , std::ostream_iterator<int>(cout, ", "));
cout << std::endl;
// delete the set
set.reset();
cout <<"After delete first \n";
// delete the set again
set.reset();
cout <<"After delete second \n";
// set also deleted here through RAII
}
I'm adding another answer here because previous answers focus very strongly on manually managing that memory, while the correct answer is to avoid having to deal with that in the first place.
void main() {
std::vector<int> set (100);
cout << "memory allocated\n";
//use set
}
This is it. This is enough. This gives you 100 integers to use as you like. They will be freed automatically when control flow leaves the function, whether through an exception, or a return, or by falling off the end of the function. There is no double delete; there isn't even a single delete, which is as it should be.
Also, I'm horrified to see suggestions in other answers for using signals to hide the effects of what is a broken program. If someone is enough of a beginner to not understand this rather basic stuff, PLEASE don't send them down that path.

C++ - need help understanding the delete function

I've been having trouble understanding the delete and delete [] functions in C++. Here's what I know so far:
aClass *ptr = new aClass(); //Allocates memory on the heap for a aClass object
//Adds a pointer to that object
...
delete ptr; //ptr is still a pointer, but the object that it
//was pointing to is now destroyed. ptr is
//pointing to memory garbage at this point
ptr = anotehrOjbectPtr //ptr is now pointing to something else
In the case that this happens,
aClass *ptr new aClass();
...
ptr = anotherObjectPtr
the object that pointer was pointing to, is now lost in memory, adn this will cause a memory leak. The object should've been deleted first.
I hope the above is correct
But I wrote this small program, where I'm getting some unexpected behaviour
#include <iostream>
#include <string>
using namespace std;
class Database {
private:
Database() {
arrNames = NULL;
capacity = 1;
size = 0;
}
Database(const Database &db) {}
Database &operator=(const Database &db) {}
string *arrNames;
int capacity, size;
public:
static Database &getDB() {
static Database database;
return database;
}
void addName(string name) {
if (arrNames == NULL) {
arrNames = new string[capacity];
}
if (size == capacity - 1) {
capacity *= 2;
string *temp = new string[capacity];
int i = 0;
while (i <= size) {
temp[i] = arrNames[i];
i++;
}
delete [] arrNames;
arrNames = temp;
}
arrNames[size] = name;
size++;
}
void print() {
int i = 0;
while (i <= size) {
cout << arrNames[i] << endl;
i++;
}
}
};
int main() {
Database &database = Database::getDB();
Database &db = Database::getDB();
Database &info = Database::getDB();
database.addName("Neo");
db.addName("Morpheus");
info.addName("Agent Smith");
database.print();
db.print();
info.print();
}
In the addName function, when I call delete [] arrNames, what I think is happening is that the memory associated with the current array arrNames is destroyed, so arrNames is now pointing at garbage, Then arrNames is directed to point to another location in memory that is pointed to by temp. So if I hadn't called delete [] arrNames, then that location in memory would've been invalid, causing a memory leak. However, when I comment out that line, the code still works without problems. Am I not understanding something here?
Sorry that this si so long
Thanks for the halp
However, when I comment out that line, the code still works without problems. Am I not understanding something here?
An important thing to know about programming is that doing things correctly is not merely a matter of having things apparently work.
Often times you can try something out hand have things appear to work, but then some outside circumstances change, something you're not explicitly controlling or accounting for, and things stop working. For example you might write a program and it runs find on your computer, then you try to demo it to someone and happen to run it on their computer, and the program crashes. This idea is the basis of the running joke among programmers: "It works for me."
So things might appear to work, but in order to know that things will work even when conditions change you have to meet a higher standard.
You've been told how to do things correctly with delete, but that doesn't necessarily mean that things will break in an obvious way if you fail to do so. You need to abandon the idea that you can definitively determine whether something is correct or not by trying it out.
From what I think I see in your code, it looks like addName() is meant to append the new name onto the dynamic array. Doing this yourself can be headache inducing, and there is an existing convenient STL template for just this which I strongly recommend, called vector, from the <vector> header.
If you add #include <vector> and change string *arrNames to vector<string> arrNames, then your entire addName() function can be reduced to:
void addName(string name){
arrNames.push_back(name);
}
From the vector.size() method, you can determine the current length of the vector as well, and your members capacity and size are no longer needed.
A memory leak doesn't involve anything being made invalid. Quite the reverse, it's a failure to make a memory location invalid, causing it to remain in use even when it shouldn't be.
First of all, when you delete something, you are not destroying it in memory, just making it available for some further allocation. This is somewhat similar to filesystem - when you delete file, you just say space it occupied is now available for some new data. You could actually retrieve unmodified data after you called delete on them, but this is undefined behavior and will be compiler/OS specific.
If you don´t delete[] arrNames, you leave its data forgotten in your process´s memory, and creating memory leak. But beside this fatal flaw, there is no more magic happening.

Where to properly delete dynamically allocated object in loop in C++

Tutorials, searches, and the dim memory of my C++ formal education have left me clueless as to where I should use delete when I'm using a dynamically allocated object pointer in a loop, such as:
// necessary files are included, this code is within main
T * t;
t = foo.getNewT();
while (!t->isFinalT()) {
// print t stuff
delete t; // is this where I should delete t?
t = foo.getNewT();
}
delete t;
This lack of knowledge has become particularly troublesome on a recent class project. On my laptop (Linux Mint, g++ Ubuntu/Linaro 4.7.3-1ubuntu1) the code ran fine without the delete statement and crashed when I added the delete statement. On the school server (Solaris, g++ (GCC) 3.4.5), the code segfaulted after a few iterations without the delete statement, and runs fine when I add the delete statement.
How do I handle this kind of loop properly so that it will run in most environments?
Additional Info:
The error on my laptop occurs when the program reaches the delete request:
*** Error in 'program': free(): invalid next size (fast):...
Some of the other code:
// T.h
class T {
int id;
int num;
int strVarPos;
char * strVar;
public:
T();
~T();
// + misc. methods
}
// T.cpp
T::T() {
id = 0;
num = -1;
strVarPos = 0;
char * strVar = new char[11];
strVar[0] = '\0'
}
T::~T() {
delete [] strVar;
}
// Foo.cpp
T * Foo::getNewT() {
T * t = new T;
// populate T's fields
return t;
}
Resolution:
Because a simple test with just T * t and the loop worked ok, I ended up reconstructing the project starting from blank and adding one class at a time, to see when the problem would appear. Turns out that I had added additional content into a dynamically allocated array elsewhere in the program without updating the size constant I was using to initialize the array.
Evidently the school server could only handle the resulting memory discrepancy without crashing if I was making sure to delete the pointers properly (the program didn't run long enough to cause a significant memory leak in my tests), while my laptop wouldn't notice the memory discrepancy until I attempted to call delete (and then would crash).
Assuming that foo.getNewT() is handing ownership of the memory over to the caller:
T * t;
t = foo.getNewT();
//while (!t->isFinalT()) // if foo.getNewT ever returns NULL, this will be UB!!!
while (t != nullptr && !t->isFinalT())
{
// ...
delete t; // if you now own it and are no longer going to use it, yes, delete it here
t = foo.getNewT();
}
delete t; // you also need this one to delete the "final" t
However, you can avoid having to do it yourself by using std::unique_ptr:
std::unique_ptr<T> t;
t.reset(foo.getNewT());
while (t && !t->isFinalT())
{
// ...
t.reset(foo.getNewT());
}
Alternatively, you could rewrite the loop to flow a bit better:
std::unique_ptr<T> t;
do
{
t.reset(foo.getNewT());
if (t)
{
// do stuff with t
}
} while (t && !t->isFinalT());
the code ran fine without the delete statement and crashed when I
added the delete statement.
Are you sure getNewT is handing ownership of the T* to you? If you delete it, and then it tries to delete it later, you will end up with a heap corruption. If it is handing ownership over to the caller, and you do not delete it, you get a memory leak.
With the additional information in your edit:
char * strVar = new char[11];
That line is unnecessary if you declare strVar as either a std::string or a char[11]. If you attempt to copy any of those T objects, you'll be using the default copy constructor (as you have not defined one), which will do a shallow copy (that is, copy the value of the pointer for strVar). When you delete 2 Ts that are both pointing to the same memory location, you get a heap corruption. The most robust solution would be to declare strVar as a std::string.
The problem is not the delete. You have put it in the right place. It's more likely something else you are doing that is causing undefined behaviour.
Note that you should have a delete t after the loop as well (to catch the last one). This is assuming that foo.getNewT() always returns a valid pointer (which it must, because you never check if it is NULL).
You should delete a dynamically allocated memory when you no longer need it. If you want t to hold its value inside the for loop, then delete it outside the loop otherwise delete it inside.
However, the best thing to do is to use std::unique_ptr when you really have to use pointers . It will take care of deallocating the memory itself when all references to the memory are destroyed. You should try to avoid allocating memory as much as you can. Use STL containers if they fit the job.
I think when you delete t you are deleting the real object inside your structure.
Maybe that what is causing the problem.

Do I have to delete this object? (if I don't intend to be ever deleted)

I have programmed a little software and wanted to create a new object on the heap. In the class member function I thus have
void gShop::CreateCustomer(int type, int number)
{
vSlot[number] = new gCustopmer(type);
vSlot[number]->itsContactToShop=itsShopNumber;
vSlot[number]->itsNumber=number;
}
where vSlot is a vector of pointers to customer objects. I have a (here: abbreviated) class gShop, in essence:
class gShop : public gBranch
{
public:
gShop(): vSlot(100){}
~gShop(){}
std::vector <gCustomer*> vSlot;
...
}
and in main I call the member function to create new customers..
vShop[0].CreateCustomer(TYPE_M20, 1);
vShop[0].CreateCustomer(TYPE_F40, **2**);//EDIT:typo previously here. I intend to create customers by reading a file later on.
std::cout<< "1" << vShop[0].vSlot[1]->itsTypeString << std::endl;
std::cout<< "2" << vShop[0].vSlot[2]->itsTypeString << std::endl;
I know that I have created with "new" two objects on the "heap" (if I handle the terminology right - sorry I am quite new to programming without formal education) and I also have two pointers to that objects stored in a vector within the object shop[0].
My question is I heard the saying that for every new there is a delete. Where do I have to delete this object? I am actually not planning on deleting any created shop or customer object in the program.
Secondly, is this code so far okay in terms of not causing memory leaks? I am a bit worried that I created the new object within a member function class, so should I try to implement delete in the destructor to gShop and set the pointer to NULL - in the theoretical case I should ever want to delete shop[0]?
Many thanks.
In the way you have written your code, you should expand you destructor implementation for gShop to iterate over the vector<> vSlot and delete each element. Because you have memory that has to be managed in this way to prevent a memory leak, you are also required to follow the Rule of Three. So, you also need to do something during copy construction (a deep copy), and you have to do something for the assignment operator (cleanup up the vector<> that is about to be copied over, and do a deep copy).
You can avoid these issues, and allow your object to use the default destructor, copy constructor, and assignment operator, by using a smart pointer instead. For example:
std::vector<std::shared_ptr<gCustomer>> vSlot;
When you create an element in the vSlot, you could use make_shared():
vSlot[number] = std::make_shared<gCustopmer>(type);
The smart pointer will delete the memory for you when there are no more references to the memory. If you don't have C++.11 available to you, you can use boost::shared_ptr instead.
The smart pointer will make it so that a copy of your gShop will share the same pointers as the original gShop it copied from. The smart pointer makes that situation okay, since there will not be multiple delete calls on the same memory. However, if you need the deep copy semantics, then you would still need to implement your own copy constructor and assignment operator to make the deep copies.
If you want something that will clean up automatically like a smart pointer, but still give you a deep copy with the default copy constructor and default assignment operator, then you can try to use boost::optional.
If you are using g++ version 4.4 or higher, then you should be able to enable C++.11 features with -std=gnu++0x, or -std=c++0x if you don't want GNU extensions. If you have g++ 4.7 or higher, then the options are -std=gnu++11 or -std=c++11.
Every time you create object with new piece of memory is taken from the heap. Only way to communicate with this memory is via pointer you got from new. When you use delete on that pointer memory is freed and may by used for other purposes. So when you lose pointer you create memory leak.
In your code the right way is:
Start with the vector with null pointers.
When you create object in exact position check pointer. If it is not null you already have object and have to delete it (or maybe throw error)
void gShop::CreateCustomer(int type, int number)
{
if(vSlot[number] != 0) {
delete vSlot[number];
vSlot[number] = 0;
}
vSlot[number] = new gCustopmer(type);
vSlot[number]->itsContactToShop=itsShopNumber;
vSlot[number]->itsNumber=number;
}
When the vector is destroyed you need to free all memory within it. So you destructor will be something like this:
gShop::~gShop() {
for(int i = 0; i < (int)vSlot.size(); ++i) {
delete vSlot[i];
}
}
Yes any memory that is allocated from the heap must be freed!
With the "new" you are allocating memory from the heap that is the sizeof gCustomer.
A good place to deallocate your memory would be in your destructor: ~gShop()
Memory leaks are caused by not deallocating your memory, although once your close your program all the memory is freed automatically.
gShop needs to delete the gCustomer objects that it creates. It can do that in its destructor, eg:
class gShop : public gBranch
{
public:
...
~gShop()
...
};
gShop::~gShop()
{
std::vector<gCustomer*>::iterator iter = vSlot.begin();
std::vector<gCustomer*>::iterator end = vSlot.end();
while (iter != end)
{
delete *iter;
++iter
}
}
Or:
void deleteCustomer(gCustomer *customer)
{
delete customer;
}
gShop::~gShop()
{
std::for_each(vSlot.begin(), vSlot.end(), deleteCustomer);
}
However, you would still have a memory leak. You are storing two separate gCustomer objects in the same vSlot[1] slot of vShop[0], so you are losing track of one of your customers. I suspect you meant to do this instead:
vShop[0].CreateCustomer(TYPE_M20, 1);
vShop[0].CreateCustomer(TYPE_F40, 2); // <-- was previously 1
std::cout<< "1" << vShop[0].vSlot[1]->itsTypeString << std::endl;
std::cout<< "2" << vShop[0].vSlot[2]->itsTypeString << std::endl;
That being said, you should re-think your design and let the STL handle all of the memory management for you, eg:
class gShop : public gBranch
{
public:
std::vector <gCustomer> vSlot;
...
};
void gShop::CreateCustomer(int type)
{
vSlot.push_back(type);
gCustomer &cust = vSlot.back();
cust.itsContactToShop = itsShopNumber;
cust.itsNumber = vSlot.size()-1;
}
vShop[0].CreateCustomer(TYPE_M20);
vShop[0].CreateCustomer(TYPE_F40);
// remember that vectors are 0-indexed
std::cout<< "0" << vShop[0].vSlot[0].itsTypeString << std::endl;
std::cout<< "1" << vShop[0].vSlot[1].itsTypeString << std::endl;
Or:
class gShop : public gBranch
{
public:
std::vector <std::shared_ptr<gCustomer> > vSlot;
...
};
void gShop::CreateCustomer(int type)
{
std::shared_ptr customer = std::make_shared<gCustomer>(type);
customer->itsContactToShop = itsShopNumber;
customer->itsNumber = vSlot.size();
vSlot.push_back(customer);
}
vShop[0].CreateCustomer(TYPE_M20);
vShop[0].CreateCustomer(TYPE_F40);
std::cout<< "0" << vShop[0].vSlot[0]->itsTypeString << std::endl;
std::cout<< "1" << vShop[0].vSlot[1]->itsTypeString << std::endl;

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];
}