Creating Arrays Using the Free Store

Hello everyone. I’m trying to teach myself programming, so I picked up this book and I’m working all the exercises. I’ve run into a stumbling block on one of them. The problem is not so much how to write the code, it's that I don't exactly understand what the exercise wants me to do. Here is the exercise in question:

a)Write a native C++ program that allows an unlimited number of values to be entered and stored in an array allocated in the free store. The program should then output the values, five to a line, followed by the average of the values entered. The initial array size should be five elements. The program should create a new array with five additional elements, when necessary, and copy values from the old array to the new.

b)Repeat the previous exercise, but use pointer notation throughout instead of arrays.

There are three issues that I don't understand.

1) The exercise specifies that the array should initially have five elements. Why is it supposed to have an initial size in the first place, when the array is supposed to be unlimited?

2) The exercise specifies that the program should create new arrays when necessary. Why is it necessary to create a new array, if the array is supposed to be unlimited? Shouldn't one unlimited array suffice?

3) Part b) requires the program to be rewritten, this time with pointer notation throughout. Initially, the program is supposed to store the values in the free store. Doesn't that mean you are already using pointers?

Below is the code I have written so far. Any help pointing me in the right direction would be greatly appreciated.


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
#include <iostream>
#include <iomanip>

using std::cin ;
using std::cout ;
using std::endl ;
using std::setw ;

int main()
{
	//Initialize pointer,  array sizer, and counter
	int* pArray = nullptr ;
	int MAX = 0 ;
	int total = 0 ;

	//Prompt input for size of array
	cout << endl << "How many numbers do you want to enter? " ;
	cin >> MAX ;
	
	//Set address of pointer to array sizer
	pArray = new int[ MAX ] ;

	//Prompt input for array elements
	cout << endl << "Input desired integers: " ;

	//Enter elements for array
	for ( int i = 0 ; i < MAX ; i++ )
	{
		//Input variable 
		int input = 0 ;
		cin >> input ;

		//Assign input variable to each array element
		*( pArray + i ) = input ;

		//Sum of all elements
		total = ( *( pArray + i ) ) + total ;

	}

	//Find average of all elements
	double average = 0.0 ;
	average = ( static_cast<double>( total ) / static_cast<double>( MAX ) ) ;

	//Output array elements
	cout << endl ;
	for ( int i = 0 ; i < MAX ; i++ )
	{
		if ( i % 5 == 0 ) 
			cout << endl ; 
		cout << setw( 5 ) << *( pArray + i ) ;
	}

	//Output average of elements
	cout << endl << endl << "The average of the elements is : " 
		 << average << endl << endl  ;

	//Delete pointer and free up memory from heap
	delete [] pArray ;
	pArray = nullptr ;

	return 0 ;
}
mtmsl wrote:
The exercise specifies that the array should initially have five elements. Why is it supposed to have an initial size in the first place, when the array is supposed to be unlimited

This is because you don't know how many numbers the user will enter - "...Write a native C++ program that allows an unlimited number of values to be entered"

mtmsl wrote:
Why is it necessary to create a new array, if the array is supposed to be unlimited? Shouldn't one unlimited array suffice?

How exactly do you intend to create an unlimited array?

The instructions are very clear as to how to accomplish this.
1. You first create an array of 5 elements.
2. When this is array is filled with numbers, you increase the size of the array
3. You do this by first creating a new array with size = (size of previous array + 5)
4. Then you copy all the contents of the previous array into this new array and start using this new array. (Make sure to delete the other one at this point)
5. When this new array is full, you repeat steps 2-4

mtmsl wrote:
Doesn't that mean you are already using pointers

Yes, but for this part instead of using the bracket notation familiar with arrays, you use pointer notation. So something like:

*(myarray + k) = 7;
where k represents the index you are wanting to assign the value 7 to
Last edited on
I figured out what it was asking for after reading through the response and looking at some examples. Here is the program I wrote for part a):

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
#include <iostream>
#include <iomanip>

using std::cin ;
using std::cout ;
using std::endl ;
using std::setw ;

int main()
{
	int* pArray = nullptr ;
	int* resize_pArray = nullptr ;
	int size = 5 ;
	int counter = 0 ;
	char input = 'y' ;

	//Declare initial array on the heap
	pArray = new int[ size ] ;

	//Input values
	while ( 'y' == input )
	{
		//Input values into original array
		cout << "Enter a value: " ;
		cin >> pArray[ counter ] ;

		//Reassign old array to new when size exceeded
		if ( counter == ( size - 1 ) )
		{
			//Resize the array
			size = ( size + 5 ) ;

			//Initialize new array on the heap
			resize_pArray = new int[ size ] ;

			//Copy old array to new array
			for ( int i = 0 ; i < size ; i++ )
				resize_pArray[ i ] = pArray[ i ] ;

			//Delete original array. 
			//Copy new array back into old array.
			delete[] pArray ;
			pArray = nullptr ;
			pArray = new int[ size ] ;
			pArray = resize_pArray ;
			
			//Resize counter for next input
			counter = ( size - 6 ) ;
		}

		++counter ;

		cout << "Do you want another value? (y/n) " ;
		cin >> input ;

	}

	//Output array
	cout << endl << "Your values are: " << endl << endl ;

	for ( int i = 0 ; i < counter ; i++ )
	{
		if ( i % 5 == 0 ) 
			cout << endl ; 
		cout << setw( 5 ) << *( pArray + i ) ;
	}

	//Find average of all elements
	int total = 0 ;

	for ( int j = 0 ; j < counter ; j++ )
	{
		total += *( pArray + j ) ;
	}
	double average = 0.0 ;
	average = ( static_cast<double>( total ) / static_cast<double>( counter ) ) ;

	//Output average 
	cout << endl << endl << "The average of your values is: " << average << endl<< endl  ;
	/*
	cout << endl << counter << endl  ;
	*/
	//Delete memory on the heap & reset pointers
	delete[] pArray ;
	pArray = nullptr ;
	/*delete[] resize_pArray ;
	*/
	resize_pArray = nullptr ;

	return 0 ;
}


This did lead me to another question, however. I deleted the arrays and reset the pointers to null at the end of program, to free up the memory. However, when I tried to delete the new array (resize_pArray) on line 86, I got a runtime error. When I commented out the line, the program ran fine. I don't understand what caused that.
You have memory leaks in your code, an example is this:
43
44
45
pArray = nullptr ; //redundant
pArray = new int[ size ] ;// memory leak here
pArray = resize_pArray ; // this is all you need 


In regards to your question, you already freed all memory at line 84, so doing it again doesn't make sense.
Setting a pointer to null after delete keyword is good practice that prevents mem leaks...no? ...Well I guess you don't have to set the pointer directly to NULL if you are going to use it right after deleting. Okay...so next concern..

I don't know how to copy the lines from the code so heres what i got..
You got a mem leak here because you set the pArray to something different and that memory is still floating around in the heap uncleared with no way of getting that location back and freeing it up.. So the correct way would be to do this.

1
2
3
4
		
 pArray = new int[ size ] ;   //line 44
 delete[] pArray;           //free up that array in the heap
 pArray = resize_pArray ;   //line 45 
Last edited on
Ok, let me see if I’ve got it straight. The reason I got the error on line 86 is because resize_pArray and pArray point to the same address. When I deleted pArray at line 84, the address pointed to by resize_pArray was already gone when I tried to delete it on line 86, thus causing the error message.

The memory leak on line 44 was due to the fact that I had already reserved memory on the heap for pArray on line 18. When I deleted pArray on line 42, the information in pArray was gone, but the memory for pArray itself was still reserved. Therefore, when I declared a new pArray at line 44, that was a new block of memory, which never got used.

My thinking in doing this was that I needed to declare pArray again because the array was being resized. However, since resize_pArray was expanded (+5) and copied back into pArray on line 45, that took care of resizing the array, since the “size” variable was changed to (size + 5). Therefore, I only needed to declare pArray once on line 18, and simply copy resize_pArray into pArray on line 45.

One other thing that was throwing me off. I had to delete pArray on line 42 before copying the new array back into it. At first, I couldn’t figure out why I could delete pArray without affecting resize_pArray, but I can’t do it vice versa. My assumption is that since resize_pArray has been expanded on line 38, it’s no longer the same as pArray. Therefore, when I delete pArray on line 42, it’s not the same as resize_pArray anymore, thus the latter is unaffected. The reason I can’t delete resize_pArray after line 45 is that pArray and resize_pArray now point to the exact same thing, so deleting one deletes the other, as in line 84.

EDIT: I also noticed another place where there might be a memory leak. On line 34 I created a new resize_pArray on the heap. Since it's in the while loop, I'm wondering if that means new memory is being reserved every time the loop iterates. Under that assumption, I inserted a line to delete resize_pArray every iteration before reserving more memory.
1
2
3
4
			//Initialize new array on the heap
                        delete[] resize_pArray ;
			resize_pArray = new int[ size ] ;

I ran the program and it works fine. I'm just wondering if my reasoning is sound about needing to delete resize_pArray before reserving new memory.
Last edited on
Ok, I found a solution for this exercise and figured out what I was doing wrong.
I did have a memory leak with resize_pArray. What I needed to do was set resize-pArray to nullptr after I copied it back into the original pArray on line 45. I didn't need to delete it since it was the same address as in pArray. I just needed to reset resize_pArray to address the memory leak. Putting this after line 45 took care of every iteration in the while loop.

Thanks for all the help. It steered me in the right direction.
Topic archived. No new replies allowed.