Memory leak

Hi I seek help from experts in c++
I have the following code im working with dynamic array
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//The value item is inserted into the Container at the location 
//  determined by index
void Container::insert(int item, int index){
	if (index < 0 || index > capacityC - 1 || index > sizeC) {
		cout<<"*** Illegal location to insert -- "<<index;
		cout<<". Container unchanged. ***"<<endl;
		return;
	}
	// Move all elements up one position.  i is destination.
	int *dest = elements+index;
	int *tail = elements+sizeC;
	while (tail > dest){
		*tail = *(tail-1);
		tail--;
	}
		*dest = item; // put value in vacated position
		dest = NULL;
		tail = NULL;
		//delete dest;
		//delete tail;
	sizeC++; // update count of items 
	return;
}


with my class private
1
2
3
4
 private:
   int sizeC;                // current size of Container
   int capacityC;            // currant capacity of dynamic array
   int * elements;            // pointer to dynamic array 


I have asked my lecturer about this code and she said. that this has memory leak.
the function should be changed such that it will allocate more momory when it is needed.
I know its part of my assingment and Im suppost to do it. But im really stuck on it and any help would be really appreciated.
Thank you.
Last edited on
Given that code I don't see a memory leak. If dest and tail are being dynamically allocated with new, change
17
18
19
20
		dest = NULL;
		tail = NULL;
		//delete dest;
		//delete tail; 

to
17
18
		delete dest;
		delete tail;
My code just crashes at comand window and i dont know what im doing wrong spent time googling and reading thought meterials but couldnt find answer :(
my class file.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

#include <iostream>
using namespace std;

const int DEFAULT=32;

class Container{
	friend bool operator==(const Container &rhs,const Container &lhs);
 public:
   Container(int maxCapacity = DEFAULT);
   ~Container();
   Container(const Container & origCont);
   const Container & operator=(const Container & rightCont);
   bool empty() const;
   void insert(int item, int index);
	void erase(int index);
	int size()const;
   void display(ostream & out) const;
 private:
   int sizeC;                // current size of Container
   int capacityC;            // currant capacity of dynamic array
   int * elements;            // pointer to dynamic array
  }; //--- end of Container class

//---test for equal elements values in the two containers rhs and lhs
bool operator==(const Container &rhs,const Container &lhs){
	if (rhs.sizeC == lhs.sizeC) {
		return true;
	}
	return false;
}

//---Default constructor:
Container::Container(int maxCapacity){	
	int * intPtr = elements;
	intPtr = NULL;
	capacityC = maxCapacity;
	sizeC = 0;
	intPtr = new int[maxCapacity];
	for (int i=0; i<maxCapacity; i++) {
    intPtr[i] = sizeC;    // Initialize all elements to zero.
	}
	assert(intPtr);
}

//----Destructor:
Container::~Container() {  
	delete [] elements;  // Free memory allocated for the a array.
}

//Copy constructor: constructs a copy of origCont.
Container::Container(const Container & origCont){
	elements = new int[origCont.capacityC];
	capacityC = origCont.capacityC;
	sizeC = origCont.sizeC;
	memcpy(elements, origCont.elements, sizeof(int) * sizeC);
}
   // Assignment operator : assigns a copy of the rightCont to 
   //the current object. A const reference to this Container is returned.
const Container & Container::operator=(const Container & rightCont){
	if(this == &rightCont) return *this; // handling of self assingment
	delete[] elements; // freeing previouslt used memory
	elements = new int[rightCont.capacityC];
	capacityC = rightCont.capacityC;
	sizeC = rightCont.sizeC;
	memcpy(elements, rightCont.elements, sizeof(int) * sizeC);
	return *this;
}

 // Returns true if the Container is empty, false otherwise.
bool Container::empty() const {
	if (sizeC == 0 ) {
		return true;
	}
	return false;
}

//The value item is inserted into the Container at the location 
//  determined by index
void Container::insert(int item, int index){
	if (index < 0 || index > capacityC - 1 || index > sizeC) {
		cout<<"*** Illegal location to insert -- "<<index;
		cout<<". Container unchanged. ***"<<endl;
		return;
	}
	// Move all elements up one position.  i is destination.
	int *dest = elements+index;
	int *tail = elements+sizeC;
	while (tail > dest){
		*tail = *(tail-1);
		tail--;
	}
		*dest = item; // put value in vacated position
		sizeC++; // update count of items 
	return;
}

//The value at the location determined by index is removed, 
//   provided index is a legal location
void Container::erase(int index){
	if (index < 0 || index > capacityC || index > sizeC) {
		cout<<"*** Illegal location to erase -- "<<index;
		cout<<". Container unchanged. ***"<<endl;
		return;
	}
	int* dest = elements+index;
	int* tail = elements+sizeC;
	// Move all elements up down position.  i is destination.
	while ( tail < dest){
		*tail = *(tail+1);
		tail++;
	}
   sizeC--; // update count of items
   return;
}

/*Returns the number of elements currently stored in this Container*/
int Container::size()const {
	return sizeC;
}

//The Container represented by this Container object has been
//   inserted into out. 
void Container::display(ostream & out) const{
	for (int i = 0; i < sizeC; i++) {
			out<<elements[i];
			out<<" ";
	}
}

//------ Prototype of oveloaded output operator
ostream & operator<< (ostream & out, const Container & aCont){
	aCont.display(out);
	return out;
}

and my main cpp file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include "cont.h"
using namespace std;

// prints a Container object passed by value
// used for testing the copy constructor
void print (Container aContainer){
   cout << aContainer << endl;
}

int main(){
   int numElems;
   cout << "Enter capacity required: ";
   cin >>numElems; //try first 9, then 50

   cout << "\n*** Next:  Container cont1(numElems);\n";
   Container cont1(numElems);
   for (int i = 0; i < 6; ++i){
      cout << "*** Next: cont1.insert("<<i<<", "<<i<<")\n";
      cont1.insert(i, i);
   }

	cout<< "\n initial  cont1\n";
	print (cont1);
	cont1.insert(25,2);
	cout<< "\n  cont1 after  insert 25 at location 2:\n";
	print(cont1);
	
	cout << "\n*** Next: Container cont2;\n";
   Container cont2(20);
	for(int i=0;i<5; ++i){cont2.insert( 10*i,i);}
	cout << "\n*** Next: print(cont2);\n";
   print(cont2);

   cout << "\n*** Next: Container cont3;\n";
   Container cont3;
	cout << "\n*** Next: print(cont3);\n";
   print(cont3);
   cout << "\n*** Next: cont3 = cont2;\n";
   cont3 = cont2;
   cout << "\n*** Next: print(cont3);\n";
   print(cont3);
	

	cout << "\n*** Next: print(cont2)\n";
   print(cont2);
   if (cont1==cont2) cout<<"Equal containers: 1 and 2\n";
   else cout<<"Non-Equal containers 1 and 2\n";
		
	if (cont2==cont3) cout<<"Equal containers: 2 and 3\n";
   else cout<<"Non-Equal containers 2 and 3\n";
	
	cout << "*** Next: cont2.insert("<<100<<", "<<7<<")\n";
   cont2.insert(100, 7);

   cout << "\n*** Next:  Bye!\n";
   return 0;
}

what am i doing wrong :(
Last edited on
if i declare functions in seperate file
say container.h and with
1
2
#ifndef Container_H
#define Container_H 

at top and
 
#endif 

at bottom
and make
container.cpp file
with
 
#include "container.h" 

and have all my functions declared there and run it in main
with makefile
1
2
3
4
5
6
7
8
a3.exe		: a3.o  container.o 
	g++ -Wl,-s -o a3.exe a3.o  container.o 

a3.o		:  a3.cpp container.h 
	g++ -c -fpermissive -fconserve-space a3.cpp

container.o	:  container.cpp  container.h 
	g++ -c -fpermissive -fconserve-space container.cpp

in gcc build then run
its works fine.....
but when i put them in one h file it gets error.....
please someone help me.
Last edited on
You aren't meant to put functions in header files.
im sorry i do not understand chrisname.
when i type in 0 it works but if i type in number greater than 0 it fails...
Last edited on
So it compiles and runs, but it crashes when you type in a number that is larger than 0? Have you tried running it with a debugger?

Edit: also, try using assertions and strategically-placed "std::cout" or "printf()"s to see what line the program crashes at, e.g.
1
2
3
...
std::cout << __FILE__ << ":" __LINE__ " : " << __func__ << std::endl; // Note: __func__ is lowercase
...

I believe those macros are pretty much universal. gcc definititely has them anyway.
Last edited on
yes. i did which pointes to error at
 
cont1.insert(i, i);

which points to
 
*dest = item; // put value in vacated position 

in my insert function

program received signal SIGSEGV, Segmentation fault.
thats why i thought its problem with memory leak.
Last edited on
You never seem to assign memory to your main memory holder 'elements':

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//---Default constructor:
Container::Container(int maxCapacity)
{
	int * intPtr = elements;
	intPtr = NULL;
	capacityC = maxCapacity;
	sizeC = 0;
	intPtr = new int[maxCapacity];
	for (int i = 0; i < maxCapacity; i++)
	{
		intPtr[i] = sizeC; // Initialize all elements to zero.
	}
	assert(intPtr);
}


You assign the memory to the local variable initPtr which gets lost as soon as the constructor exits.

That is your memory leak.
OMG ur right.
I changed code
1
2
3
4
5
6
7
8
9
10
//---Default constructor:
Container::Container(int maxCapacity){	
	capacityC = maxCapacity;
	sizeC = 0;
	elements = new int[maxCapacity];
	for (int i=0; i<maxCapacity; i++) {
    elements[i] = sizeC;    // Initialize all elements to zero.
	}
	assert(elements);
}

and it runs properly now.
thank you so so much in taking time to help me. :)
The constructor is the place to assign memory to your class member variables like 'elements'.

In fact those members really should be initialised in the 'initialization list:

Read this: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//---Default constructor:
Container::Container(int maxCapacity)
: sizeC(0)
, capacityC(maxCapacity)
, elements(new int[maxCapacity])
{
	int * intPtr = elements;
	for (int i = 0; i < maxCapacity; i++)
	{
		intPtr[i] = sizeC; // Initialize all elements to zero.
	}
	assert(intPtr);
}
Topic archived. No new replies allowed.