This is my program, it causes memoryleaks. I show only a small part where the problem exist. Starts with the header then the cpp.

ParticipatorRegister.h

#ifndef PARTICIPATORREGISTER_H
#define PARTICIPATORREGISTER_H
#include "Participator.h"

class ParticipatorRegister{
private:
	Participator **arr;
	int inc, init, elem;
	void initiate();
	//void expand();
public:
	ParticipatorRegister();
	~ParticipatorRegister();
	//void save(ofstream&);
	//void read(ifstream&);
	//void add(string, string);
	//void show(int);
	//void showPaid();
	//void showNotPaid();
	//void findPerson(string);
	//void alterInfo(string);
	//void remove(string);
};
#endif

Participator.cpp

#include "ParticipatorRegister.h"
ParticipatorRegister::ParticipatorRegister(){
initiate();
}
void ParticipatorRegister::initiate(){
	this->elem = 0;
	this->init = 10;
	this->inc = 5;
	this->arr = new Participator*[init]; // Här sätter jag arr
}
ParticipatorRegister::~ParticipatorRegister(){ // Är denna rätt?
for (int i = 0; i < init; i++) 
{
  delete [] arr[i];
  arr[i] = NULL;
}
delete [] arr;
}

I get this output from the debugger
Detected memory leaks!
Dumping objects ->
{117} normal block at 0x003960E0, 40 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
The program '[0x9A4] misc.exe: Native' has exited with code 0 (0x0).

Can anyone see the problem and tell me what to do?

Recommended Answers

All 7 Replies

Detected memory leaks!
Dumping objects ->
{117} normal block at 0x003960E0, 40 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.

That dump is not very helpful, don't you think?

As a first step, if you redefine new to DEBUG_NEW, the debugger will be able to pinpoint the memory leak, stating the type of object as well.

Add this piece of code after the headerfiles have been included:

//#include "whatever"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

PS: I've assumed visual studio, but every compiler will have a way to get this done.

Yeah I will test that, thanks :)

But do you know what to type to deallocate this memory
Participator **arr;
this->arr = new Participator*[init];
delete xxx

There are multiple issues with your code. Why are you deleting with delete[] while you should be simply deleting with delete?!

Besides that, there are other issues in your code, which I've fixed (take a good look into the constructor of your class - specifically the Initiate() method):

class ParticipatorRegister{
private:
	int **arr; //I don't know what's a Participator, so I replaced it with an integer.
	int inc, init, elem;
	void initiate();
	//void expand();
public:
	ParticipatorRegister();
	~ParticipatorRegister();
	//void save(ofstream&);
	//void read(ifstream&);
	//void add(string, string);
	//void show(int);
	//void showPaid();
	//void showNotPaid();
	//void findPerson(string);
	//void alterInfo(string);
	//void remove(string);
};

ParticipatorRegister::ParticipatorRegister(){
	initiate();
}
void ParticipatorRegister::initiate(){
	this->elem = 0;
	this->init = 10;
	this->inc = 5;
	this->arr = new int*[init]; // Här sätter jag arr

	for(int i=0; i<init; i++)
	{
		arr[i] = new int(i); //You hadn't done this allocation, but you were deleting it from destructor.
	}
}
ParticipatorRegister::~ParticipatorRegister(){ // Är denna rätt?
	for (int i = 0; i < init; i++) 
	{
		delete arr[i]; //why were you using delete[] instead?!
		arr[i] = NULL;
	}
	delete arr; //here too!
}

int main ()
{
  ParticipatorRegister obj;
  return 0;
}

If you comment out any of the delete statements, you'll see that the memory leaks will reappear.

#ifndef PARTICIPATORREGISTER_H
#define PARTICIPATORREGISTER_H



#include "Participator.h"

class ParticipatorRegister{
private:
	Participator **arr;
	int inc, init, elem;
	void initiate();
	//void expand();
public:
	ParticipatorRegister();
	~ParticipatorRegister();
	//void save(ofstream&);
	//void read(ifstream&);
	//void add(string, string);
	//void show(int);
	//void showPaid();
	//void showNotPaid();
	//void findPerson(string);
	//void alterInfo(string);
	//void remove(string);
};
#endif

cpp

#include "ParticipatorRegister.h"
ParticipatorRegister::ParticipatorRegister(){
initiate();
}
void ParticipatorRegister::initiate(){
	this->elem = 0;
	this->init = 10;
	this->inc = 5;
	this->arr = new Participator*[init]; 	
}
ParticipatorRegister::~ParticipatorRegister()
{
delete [] arr;
}

I still have memoryleaks, do you know how to remove this->arr = new Participator*[init]; properly in the destructor
Btw Participator is my class.
So i have the files: Participator.h, cpp, ParticipatorRegister.h,cpp and main.

#ifndef PARTICIPATORREGISTER_H
#define PARTICIPATORREGISTER_H



#include "Participator.h"

class ParticipatorRegister{
private:
	Participator **arr;
	int inc, init, elem;
	void initiate();
	//void expand();
public:
	ParticipatorRegister();
	~ParticipatorRegister();
	//void save(ofstream&);
	//void read(ifstream&);
	//void add(string, string);
	//void show(int);
	//void showPaid();
	//void showNotPaid();
	//void findPerson(string);
	//void alterInfo(string);
	//void remove(string);
};
#endif

cpp

#include "ParticipatorRegister.h"
ParticipatorRegister::ParticipatorRegister(){
initiate();
}
void ParticipatorRegister::initiate(){
	this->elem = 0;
	this->init = 10;
	this->inc = 5;
	this->arr = new Participator*[init]; 	
}
ParticipatorRegister::~ParticipatorRegister()
{
delete [] arr;
}

I still have memoryleaks, do you know how to remove this->arr = new Participator*[init]; properly in the destructor
Btw Participator is my class.
So i have the files: Participator.h, cpp, ParticipatorRegister.h,cpp and main.

Why are you *still* using delete[] arr?!

Did you even read my previous post and go through my code? What do you mean you have memory leaks?

Did you try my code (which uses integer instead of your class object)?! If that doesn't leak, and if the same code leaks with your class object, then there may be something to do with your class (participator).

You aren't allocating any memory for the pointer to pointer variable (or for the elements it holds as an array), but then how possibly can you delete anything from your destructor? The debugger must catch you; I'm surprised you aren't getting any runtime error while attempting to delete memory that you haven't allocated.

Please be more precise in what you're doing, or I'll not be able to help you.

I did read your last post, just typed wrong. I show you my whole program

Participator.h

#ifndef PARTICIPATOR_H
#define PARTICIPATOR_H
#include <iostream>
#include <string>
#include <fstream>

using namespace std;

class Participator
{
private: 
	string name;
	string address;
	bool paid;
public:
	Participator();
	Participator(string, string);
	~Participator();
	void setName(string);
	void setAddress(string);
	void setPaid(bool); 
	string getName() const;
	string getAddress() const;
	bool getPaid() const; 
	void save(ofstream&);
	void read(ifstream&); 
	string toString();
};
#endif

Participator.cpp

#include "Participator.h"

Participator::Participator()
{
	this->name = "None"; 
	this->address = "None";
	this->paid = false; 
}

Participator::Participator(string n, string adr)
{
	this->name = n;
	this->address = adr; 
	this->paid = false;
}

Participator::~Participator(){

}

void Participator::setName(string n)
{
	this->name = n;
}

void Participator::setAddress(string adr)
{
	this->address = adr;
}

void Participator::setPaid(bool pay)
{
	this->paid = pay;
}

string Participator::getName() const
{
	return this->name;
}

string Participator::getAddress() const
{
	return this->address; 
}

bool Participator::getPaid() const
{
	return this->paid; 
}

void Participator::save(ofstream &out)
{
	out << name << endl << address << endl << paid << endl;
}

void Participator::read(ifstream &in) 
{
	getline(in, this->name);
	getline(in, this->address);
	in >> this->paid;
}
string Participator::toString()
{
	string tmp = name + "\n";
	tmp += this->address;
	if(this->paid)
		tmp += "\nAvgift betald\n";
	else
		tmp += "\nAvgift ej betald\n";
	return tmp;
}

ParticipatorRegister.h

#ifndef PARTICIPATORREGISTER_H
#define PARTICIPATORREGISTER_H



#include "Participator.h"

class ParticipatorRegister{
private:
	Participator **arr;
	int inc, init, elem;
	void initiate();
	void expand();
public:
	ParticipatorRegister();
	~ParticipatorRegister();
	void save(ofstream&);
	void read(ifstream&);
	void add(string, string);
	void show(int);
	void showPaid();
	void showNotPaid();
	void findPerson(string);
	void alterInfo(string);
	void remove(string);
};
#endif

ParticipatorRegister.cpp

#include "ParticipatorRegister.h"
ParticipatorRegister::ParticipatorRegister(){
initiate();
}
void ParticipatorRegister::initiate(){
	this->elem = 0;
	this->init = 10;
	this->inc = 5;
	this->arr = new Participator*[init]; 	
}
ParticipatorRegister::~ParticipatorRegister()
{
delete arr;
}
void ParticipatorRegister::expand(){ 
	Participator **tmp = new Participator*[init+inc];
	for(int i = 0;i < init;i++){
		tmp[i] = arr[i];
	}
	delete [] arr;
	arr = tmp;
	init += inc;
}
void ParticipatorRegister::save(ofstream &out){
	out << elem << endl;
	for(int i = 0;i < elem;i++){
		arr[i]->save(out);
	}
}
void ParticipatorRegister::read(ifstream &in){
	in >> elem;
	string t, t2;
	bool pay;
	for(int i = 0;i < elem;i++){
		in.ignore();
		arr[i] = new Participator;
		arr[i]->read(in);
	}
}
void ParticipatorRegister::add(string name, string adr){
	if(elem == init)
	{
		expand();
	}
	arr[elem] = new Participator(name, adr);		
	elem++;	
}
void ParticipatorRegister::remove(string janne)
{															// Första fasen, kollar om det finns flera med samma namn
	bool *done = new bool[elem];							
	for(int i  = 0; i <  elem;  i++)
	{ 
		if(arr[i]->getName() == janne)					
		{
			done[i] = true;									 
			cout << (i) << "\t" << arr[i]->getName() << "\t" << arr[i]->getAddress() << endl; 
		}
		else
		{ 
			done[i] = false;
		}
	} 															// Andra fasen, kollar om id:et på den positionen har true
	int n;
	cout << "Ange id på deltagaren som du vill ta bort!" <<endl; // Skriv in id:et på användaren som ska bort 
	cin >> n; 
	cin.ignore();
	//if(done[n] == true) // Om den platser på id:et är satt till true i done får vi ta bort den
	if( n>=0 && n<elem && done[n] )
	{
		if(n == (elem-1)) // Är platsen på id:et sist i arrayen så tar vi bort den direkt
		{
			delete arr[elem-1];
			elem--;
		}
		else // Är den inte sist i arrayen så skriver vi över värderna
		{
			string name;
			string address;
			bool boolvalue;
			// hämtar värderna på sista positionen i arrayen
			name = arr[elem-1]->getName();
			address = arr[elem-1]->getAddress();
			boolvalue = arr[elem-1]->getPaid();
			// Sätter platsen som vi vill ta bort till dessa värden
			arr[n]->setName(name);
			arr[n]->setAddress(address);
			arr[n]->setPaid(boolvalue);
            // Slutligen tar vi bort den sista platsen, eftersom den redan finns på plats N nu och minskar elem
		    delete arr[elem-1];
			elem--;
		}
	}
	else
	{
		cout  <<"Not a valid number" << endl; // Finns ingen med det Id:et
	}
	delete [] done; // Ta bort bool arrayen som vi allokerade
}
void ParticipatorRegister::alterInfo(string janne){
	cout << "\nId-nr\tNamn\tAddress\n";
	for(int i = 0;i < elem;i++){
		if(arr[i]->getName() == janne){
			cout << (i+1) << "\t" << arr[i]->getName() << "\t" << arr[i]->getAddress() << endl;
		}
	}
	int n;
	cout << "\nAnge deltagare som ska ändras (id): ";
	cin >> n;
	cin.ignore();

	string tname = "", tadr = "";
	char a;
	cout << "Skriv in info som skall ändras. Tryck [Enter] om infon inte ska ändras.\n";
	cout << arr[n-1]->getName() << endl << "Ange namn: ";
	getline(cin,tname);
	if(tname != "")
		arr[n-1]->setName(tname);

	cout << arr[n-1]->getAddress() << endl << "Ange address: ";
	getline(cin,tadr);
	if(tadr != "")
		arr[n-1]->setAddress(tadr);

	if(arr[n-1]->getPaid())
		cout << "Avgift betald\n";
	else
		cout << "Avgift ej betald\n";

	cout << "Vill deltagaren ändra sin betalnings status? (y/n): ";
	cin >> a;
	cin.ignore();
	if(a == 'y')
		arr[n-1]->setPaid(!arr[n-1]->getPaid()); // ! = den läser boolvärdet omvänt. TRUE blir FALSE och FALSE blir TRUE.
}
void ParticipatorRegister::show(int ch){
	for(int i = 0;i < elem;i++){
		if(ch < 0){
			if(arr[i]->getPaid())
				cout << arr[i]->getName() << endl;
		}
		else if(ch == 0){
			if(!arr[i]->getPaid())
				cout << arr[i]->getName() << endl;
		}
		else{
			cout << arr[i]->getName() << endl;
		}
	}
}
void ParticipatorRegister::findPerson(string janne){
	for(int i = 0;i < elem;i++){
		if(arr[i]->getName() == janne){
			cout << arr[i]->toString();
		}
	}
}

main.cpp

#include "ParticipatorRegister.h"

using namespace std;

int menu(){
	string choice;
	cout << "1. Lägg till ny Deltagare" << endl
		<<  "2. Visa anmälda deltagare" << endl
		<<  "3. Visa de som har betalat sin avgift" << endl
		<<  "4. Visa de som inte har betalat sin avgift" << endl
		<<  "5. Sök efter info om deltagare" << endl
		<<  "6. Ta bort deltagare" << endl
		<<  "7. Ändra uppgifter för deltagare" << endl
		<<  "8. Spara alla deltagare på fil" << endl
		<<  "9. Öppna fil" << endl
		<<  "0. Avsluta" << endl
		<< "Ditt val: ";
	getline(cin, choice);
	
	return atoi(choice.c_str());
}

void add(ParticipatorRegister &r){
	string tmp,tmp2;
	cout << "Namn: ";
	getline(cin, tmp);
	cout << "Address: ";
	getline(cin, tmp2);
	r.add(tmp, tmp2);
}

void info(ParticipatorRegister &r, int ch){
	string name;
	cout << "Deltagare: ";
	getline(cin,name);
	
	if(ch < 0)
		r.alterInfo(name);
	else if(ch == 0)
		r.findPerson(name);
	else
		r.remove(name);
}

void mfile(ParticipatorRegister &r, bool opt){
	string fil = "";
	cout << "Filnamn: ";
	getline(cin,fil);

	if(opt){ 
		ifstream in(fil.data());
		r.read(in);
		in.close();
	}
	else{ 
		ofstream ut(fil.data(), ios::trunc|ios::out);
		r.save(ut);
		ut.close();
	}
}

int main() 
{
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
	int c;
	string hold, name;
	ParticipatorRegister reg;
 /*reg.add("Joe Smith", "100 Main Street");
   reg.add("Frank Johnson", "100 Juniper Road");
   reg.add("Sue Brown", "100 Lily Lane");
   reg.remove("Joe Smith");
   reg.add("Timothy Smalls", "325 ABC Avenue");*/

	do{
		c = menu();
		switch(c)
		{
			case 1:add(reg);//adda
				break;
			case 2:reg.show(1);//showall
				system("pause");
				break;
			case 3:reg.show(-1);//paid
				system("pause");
				break;
			case 4:reg.show(0);//notpaid
				system("pause");
				break;
			case 5:info(reg, 0);//findperson
				break;
			case 6:info(reg, 1);//remove
				break;
			case 7:info(reg, -1);//alterinfo
				break; 
			case 8:mfile(reg, 0);//skriva
				break;
			case 9:mfile(reg, 1);//läsa
				break; 
			case 0:exit(0);//döda
				break;
			default: cout << "\nGiltliga alternativ är 0-9\n\n";
				break;
		}
	}while(c != 10);
}

Some of the code is in swedish but you get the point,
the menusystem is like
1. Add
2. Show all
3. Show paid
4. Show not paid
5.Find person
6.Remove
7.Change information
8. Save to file
9. Open file
0. Exit

Why are you declaring arr like this:
Participator **arr;

instead of like this:
Participator *arr;

Your expand() method is wrong. Using vectors instead of arrays so you don't have to manage your own memory is probably the easiest way to correct this, however, the general way would be declare temp with the same memory as arr, copy arr to temp. Delete old memory from arr. Declare arr with the expanded memory desired. Copy temp back to array. Delete memory from temp.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.