Mismatch delete - c++

I have program which implements database of peoples and his companies. I have created dynamic array of pointer to class members instead of dynamic array of class members, cause copying is quicker with it.
I have version which works but valgrind shows mismatch delete in destructor (delete db)
CCompany** db;
~CCompanyIndex ( void )
{
for(unsigned i=0;i<len;i++)
{
/*cout<<"dealloc:"<<db[i]<<endl;*/
delete db[i];
}
delete db;
}
CCompanyIndex ( void )
{
max=1000;
len=0;
db=new CCompany*[max];
}
I use also to add
CCompany* newIt=new CCompany(oName,oAddr,cName,cAddr);
So I have tried following code which I consider correct previously
~CCompanyIndex ( void )
{
delete [] db;
}
But then all memory allocated by adding method is not deallocated.

The first sample is almost correct. You're deleting each element in a for loop, but then you attempt to delete the array.
for(unsigned i=0;i<len;i++) { delete db[i]; }
delete db;
It should instead be:
for(unsigned i=0;i<len;i++) { delete db[i]; }
delete[] db;
Whenever you use new ...[], you should be using delete[].
Also, don't forget the Rule of Three (or Five (or Zero)).

You are using the wrong delete. Do this:
CCompanyIndex::~CCompanyIndex()
{
for(unsigned i=0; i<len;i++) delete db[i];
delete [] db;
}
Note the delete [] call.

You need delete db[i] for each element but delete[] db for the array itself, so neither destructor was correct.
Arrays allocated with new Foo[n] must be deallocated with the array form, delete[], that's what valgrind means about mismatch new/delete

Related

2d array memory management issue

I have to write a code that gets a string and turns it into an object of a class. Everything is working as expected but I'm unable to deallocate the dynamically allocated 2d array of objects.
I know the issue is within the destructor and the Move assignment operator for the object, I keep getting SIGBRT and EXC_BAD_ACCESS errors when I try to run it.
Below is my Code for the constructor, destructor and move assignment/constructor
//CustomerOrder.cpp
CustomerOrder::CustomerOrder(std::string&
src):Name(src),Product(),ItemCount(),ItemList(),field_width(){
std::vector<ItemInfo> info;
std::string* tokens[] = { &Name, &Product };
Utilities utils;
size_t next_pos = -1;
bool more = true;
for (auto& i : tokens) {
if (!more) break;
*i = utils.extractToken(src, next_pos, more);
}
while (more){
info.push_back(utils.extractToken(src, next_pos, more));
}
if(!info.empty() && info.back().ItemName.empty()){
info.pop_back();
}
ItemCount = info.size();
ItemList = new ItemInfo*[ItemCount];
for (int i = 0; i < ItemCount; i++){
ItemList[i] = new ItemInfo(info.at(i).ItemName);
}
if (utils.getFieldWidth() > field_width){
field_width = utils.getFieldWidth();
}
}
CustomerOrder::~CustomerOrder(){
for(int i = 0; i<ItemCount;i++){
delete[] ItemList[i];
}
delete[] ItemList;
}
CustomerOrder::CustomerOrder(CustomerOrder&& src){
*this = std::move(src);
}
CustomerOrder& CustomerOrder::operator=(CustomerOrder&& src){
if(this!= &src){
delete [] ItemList;
Name = std::move(src.Name);
Product = std::move(src.Product);
ItemCount = std::move(src.ItemCount);
ItemList = std::move(src.ItemList);
src.ItemList = nullptr;
}
return *this;
}
And the ItemInfo struct
//ItemInfo struct
struct ItemInfo
{
std::string ItemName;
unsigned int SerialNumber;
bool FillState;
ItemInfo(std::string src) : ItemName(src), SerialNumber(0),
FillState(false) {};
};
You are combining "new" with "delete[]". If you use "new" use "delete" if you use "new[]" then use "delete[]" for the thing.
This is your problem there: "delete[] ItemList[i];" it should be "delete ItemList[i];" instead
This line of your code ItemList[i] = new ItemInfo(info.at(i).ItemName); doesn't allocate a dynamic array, yet this code in your destructor tries to delete it as thought it was a dynamic array.
for(int i = 0; i<ItemCount;i++){
delete[] ItemList[i];
}
A quick fix would to be to change delete[] to delete. However, it appears as though it would be much easier to simply allocate a single dynamic array. In other words, allocate ItemList as such ItemList = new ItemInfo[ItemCount]; Granted, you would have to change the type, but it makes more sense from what you posted.
Another possible issue is that in your destructor you don't check if the ItemList is a nullptr or actually allocated to anything. To which, your destructor could possibly try to access invalid data. Not only that, but your move operator deletes the ItemList without deleting the data inside of it.
You could make a function to free up the data in ItemList and then call that function from the destructor and move operator.
On a side note, why are you using dynamic 2D arrays when it appears that you know how to use vectors? A vector would handle all of this in a much simpler fashion. For example, the type would be std::vector<std::vector<ItemInfo>>.

How to delete an array of pointers to generic type objects

My class has a generic array of pointers member named A:
T** A
Currently, i delete the array in the destructor in the following way:
~MyQuickInitArray(){
delete [] A;
};
Will this cause a memory leak? if so, should i iterate through the array and call delete on each object?
On a side note - Do I need to call delete [] B if B is an array of integers or does the destructor handles it already?
EDIT:
This is how the allocation occurs:
MyQuickInitArray(int size)
{
if(size <= 0)
{
throw new std::exception;
}
_size = size;
_counter = 0;
A = new T*[size];
B = new int[size];
C = new int[size];
}
MyQuickInitArray(const MyQuickInitArray& myQuickInitArray)
{
_size = myQuickInitArray._size;
_counter = myQuickInitArray._counter;
A = new T*[_size];
for(int i = 0; i<_size ;i++)
{
if(myQuickInitArray.A[i] != NULL)
{
A[i] = new T(*myQuickInitArray.A[i]);
}
}
B = myQuickInitArray.B;
C = myQuickInitArray.C;
}
Will this cause a memory leak?
You can surely count on it if A is an array of pointers. You need loop through the array and delete the pointers yourself.
~MyQuickInitArray {
for (int i =_size; i--;) {
delete A[i];
}
delete [] A;
}
Do I need to call delete [] B if B is an array of integers or does the destructor handle it?
Yes, always delete that which is allocated with new. You can do this inside your class's destructor.
Will this cause a memory leak?
Yes, calling delete[] on the array of pointers without deleting items pointed to by individual elements will cause a memory leak, because "built-in" pointers of C++ do not have ownership semantic. Consider using "smart" pointers, e.g. unique_ptr<T> instead of "plain" ones to avoid calling destructors in a loop.
Do I need to call delete [] B if B is an array of integers
You need to call delete[] on everything that you allocated with new[], regardless of the element type of the array.

Do i have to delete wchar_t that i allocated with new?

Lets say i have a class like this:
class LolClass {
LPWSTR* stuff;
LolClass::LolClass(LPWCHAR lols) {
stuff = new LPWSTR[100];
for (int i = 0; i < 100; i++) {
stuff[i] = new wchar_t[wcslen(lols)+1];
wcsncpy(stuffs[i], lols, wcslen(lols)+1);
}
}
LolClass::~LolClass() {
delete[] stuff;
}
}
so if i call
LolClass* veryfunny = new LolClass(L"lol!");
it would make me 100 lol's, problem is when i call
delete veryfunny;
it deletes the pointer array but not the individual wchar_t's, if i try and loop through the wchar_t's and delete them then i just crash and i dont know what to do since i know for fact that they are still there even after i delete veryfunny (i checked by passing one of the pointers outside the class)
Thanks!
If you call
LolClass* veryfunny = new LolClass(L"lol!");
then you will eventually need to call:
delete veryfunny;
But for arrays, you need delete[]: stuff[i] = new wchar_t[n]; delete [] stuff[i];
In your code, you need to first loop over stuff and delete[] the elements, and then delete[] the array stuff itself.
Or just use a std::vector<std::wstring>.
Update: From what I understand, you're not actually worried about deleting *veryfunny, but rather about how to write a correct destructor for LolClass. Note that the destructor also gets invoked for global and automatic objects, e.g. { LolClass x(L"hello"); } /* boom */, so it doesn't really matter how you instantiate an object for LolClass. You have to get the class right in any case.
David Schwartz wins after all, the wchar's didnt let themselves be deleted because they werent null terminated

A question about memory leaks

#include <QList>
class MyType{
//This has some data in it....
};
QList<MyType> f()
{
QList<MyType> list;
for(int i = 0; i<10; i++ )
{
MyType* item = new MyType();
list << *item;
}
return list;
}
QList<MyType> temp_var = f();
When temp_var goes out of the scope and destroys, what happens to the items that we created and add to this list?
Is there going to be any memory leaks?
Thank you.
Yes, there will be a memory leak. As a general rule, you must have one delete for each new in your program.
In your specific case, the faulty logic happens much earlier than temp_var's destruction. You allocate the items, and then store a copy of those items in the list. You should immediately destroy the original, no-longer-useful items.
Your for loop could be :
for(int i = 0; i<10; i++ )
{
MyType* item = new MyType(); // get me an item.
list << *item; // put copy of item in list
delete item; // destroy my item
}
When expressed that way, it is obvious that we shouldn't use new at all!
for(int i = 0; i < 10; i++)
{
MyType item;
list << item;
}
This version won't leak, assuming that MyType doesn't have any memory-management bugs of its own.
EDIT: As an aside, had your program been:
QList<MyType*> f() // List of POINTERS
{
QList<MyType*> list;
for(int i = 0; i<10; i++ )
{
MyType* item = new MyType();
list << item; // Storing a POINTER
}
return list;
}
Then, yes, you would have had precisely the memory leak you expected. QList does not automatically provide delete on pointer types.
I don't see any point of using new in your code, as you're not storing the pointers in the list, rather copies of the object created with new, and you're not deleteing it. So yeah, there is memory-leak in the function itself.
Seeing that QList is not a list of pointers, I can say that you shouldn't use new in your code:
QList<MyType> f()
{
QList<MyType> list; //note : its not a list of MyType*
for(int i = 0; i<10; i++ )
{
MyType item; //automatic variable
list << item;
}
return list;
}
When a QList gets destroyed / goes out of scope, it destroys its content with it. In your case, the content is made of copies of your objects (built from the implicit copy-constructor), not the objects themselves. The memory will leak in each iteration of the for-loop since the original object created by new MyType() will lose its pointer, but will remain allocated.
There certainly will be a leak if it you don't delete all of those items you created with new MyType()!
In the destructor for QList you need to go through the list and call delete on each of those items.

How to delete an array of pointers

I've been brushing up on my C++ as of late, and I have a quick question regarding the deletion of new'd memory. As you can see below i have a simple class that holds a list of FileData *. I created an array to hold the FileData objects to be pushed into the list. When ReportData is destructed I loop through the list and delete each element. My question is, how can i delete the array when I'm done using reportData, so that I do not have any memory leaks?
Report.h
class REPORTAPI ReportData {
public:
ReportData()
{
}
virtual ~ReportData()
{
printf("Starting ReportData Delete\n");
for (list<FileData*>::iterator i = ReportFileData.begin(), e = ReportFileData.end(); i != e; )
{
list<FileData*>::iterator tmp(i++);
delete *tmp;
ReportFileData.erase(tmp);
}
for (list<SupressionData*>::iterator i = ReportSupressionData.begin(), e = ReportSupressionData.end(); i != e; )
{
list<SupressionData*>::iterator tmp(i++);
delete *tmp;
ReportSupressionData.erase(tmp);
}
ReportFileData.clear();
ReportSupressionData.clear();
printf("Finished ReportData Delete\n");
}
list<FileData *> ReportFileData;
list<SupressionData *> ReportSupressionData;
}
extern "C" __declspec(dllexport) FileData* __stdcall createFileData(string fileName, long recordCount, long addPageCount)
{
return new FileData(fileName, recordCount, addPageCount);
}
Main.cpp
ReportData *reportData = createrd();
if (reportData != NULL)
{
CreateFileDataFunc createfd (reinterpret_cast<CreateFileDataFunc>(GetProcAddress (dll, "createFileData")));
const int num_files = 5;
FileData *fileData[num_files];
char buff[256] = {'\0'};
for (int i = 0; i < num_files; i++)
{
sprintf(buff, "test: %d", i);
fileData[i] = createfd(buff, 1, 1);
reportData->ReportFileData.push_back(fileData[i]);
}
delete reportData;
reportData = NULL;
delete [] fileData; // this is throwing an access violation error:
//EAccessViolation: 'Access violation at address 326025AF. Write of address 00000008'.
}
--- I removed the delete oprations from the ReportData dtor
and I'm now looping and deleting:
for(int i = 0; i < num_files; i++)
{
delete fileData[i];
}
This is easier to understand then having to rely on a separate object's dtor to clean up memory.
You don't. fileData is an automatic (stack) variable. You didn't allocate it with new, so you don't delete it.
[Edit: also I'm not sure, but I think you could face problems deleting those FileData objects from main.cpp, considering that they were allocated in some dll. Does the dll provide a deleter function?]
Your array is not dynamically allocated, so you don't need to delete it. Each element, however, is pointing to a dynamically allocated object (from your comment):
createfd is a function pointer that returns a new instance of FileData though
What you need to do is loop over the elements of the array, and free each of them.
for(int i = 0; i < num_files; i++)
{
delete fileData[i];
}
// allocate on the stack, no manual delete required
FileData *fileData[num_files];
// allocate on the heap, must delete after usage
FileData *fileData = new FileData[num_files];
// ..
delete [] fileData;
Have you thought about wrapping FileData* with a smart pointer?
The problem with your dtor is that an exception will cause a memory leak (with some other problems relating to exceptions leaking out of dtor's).
"My question is, how can i delete the array when I'm done using reportData, so that I do not have any memory leaks?"
That's the wrong question. The right question is "who should delete these FileData objects?", and the answer is "whoever constructs them, ideally, in this cae Main.cpp". Farming out the job to reportData is awkward and precarious; doing the job twice (once in the ReportData destructor and again in Main.cpp) violates memory.
If you must destroy the objects in ~ReportData(), just don't do anything about them in Main.cpp. Then your code will be correct. Horrible, but correct.
Don't deallocate anything in main().
The destructor for reportData will handle everything allocated with createfd() (just make sure that createfd() is returning what it allocated with new(), since you must not delete anything that was not new'd).
fileData is allocated locally, on the stack, not through new. Since it wasn't allocated by new, don't delete it.
The pointers that were passed into fileData were also passed into reportData, and reportData is responsible for all deletions there. You could check to see that they weren't allocated from an inaccessible memory pool (say in a dynamically linked library); if they were, that's a problem.
So, assuming the deletes are correct in the ReportData destructor, remove any deletion of fileData and you're good.
There is no need to delete or clear either of the two lists - this will be done for you by the default destructor. Assuming that the pointers the lists contain (to "arrays"? I'm not clear) have been dynamically allocated, you need to delete them. However, you can (and should) avoid having to do this explicitly by making the lists contain std::vectors or suitable smart pointers.