hi guys I'm reading Alex Allains jumping into c++ and so far I must admit it's a pretty good book with great explanations up until this point which is why I'm asking you guys for some help he barely explains this example very much at all I'm on the section of Dynamic Memory Allocation and aub-section pointers and arrays,
could anybody please try to run through this code for me and explain why how it works,I wish Alex gave a more detailed break down of this code in his book I've been looking at it for hours now and can't figure it out anyway heres the code guys
#include <iostream>
usingnamespace std;
int* growArray (int* p_values, int *size);
void printArray (int* p_values, int size, int elements_set);
int main ()
{
int next_element = 0;
int size = 10;
int *p_values = newint[ size ];
int val;
cout << "Please enter a number: ";
cin >> val;
while ( val > 0 )
{
if ( size == next_element + 1 )
{
// now all we need to do is implement growArray
// notice that we need to pass in size as a pointer
// since we need to keep track of the size of the array as
// it grows!
p_values = growArray( p_values, & size );
}
p_values[ next_element ] = val;
next_element++;
cout << "Current array values are: " << endl;
printArray( p_values, size, next_element );
cout << "Please enter a number (or 0 to exit): ";
cin >> val;
}
delete [] p_values;
}
void printArray (int *p_values, int size, int elements_set)
{
cout << "The total size of the array is: " << size << endl;
cout << "Number of slots set so far: " << elements_set << endl;
cout << "Values in the array: " << endl;
for ( int i = 0; i < elements_set; ++i )
{
cout << "p_values[" << i << "] = " << p_values[ i ] << endl;
}
}
int *growArray (int* p_values, int *size)
{
*size = 2;
int *p_new_values = newint[ *size ];
for ( int i = 0; i < *size; ++i )
{
p_new_values[ i ] = p_values[ i ];
}
delete [] p_values;
return p_new_values;
}
That example, assuming you have copied it verbatim, is very bad.
The idea of growArray() is to increase the array size. Since you can't really change an array's size, this is done by creating a new array, copying the values from the old array to the new array, deleting the old array, and returning the new array.
It has several flaws. Line 49 I presume is a typo. Line 53 is a segmentation fault waiting to happen.
Give me a minute and I'll give you a better example...
but i removed the * because it was confusing me and was not too sure what it even did beside an = operator but apart from that the code is the direct source code from his website and example in his book
Be careful when blithely modifying code you don't understand. The *= 2 doubled the size of the array. The modified code simply sets its size to 2 (which is incorrect).
Here's my example code, which will hopefully make better sense for you.
#include <iostream>
// A dynamic array needs a lot of information associated with it:
struct Array
{
int* xs; // location of its first element in memory
int size; // the total number of elements available
int used; // the number of elements currently in use
};
// This function initializes ("constructs") a dynamic array
void construct( Array& a )
{
a.xs = nullptr;
a.size = 0;
a.used = 0;
}
// This function destroys ("destructs") a dynamic array
void destruct( Array& a )
{
delete[] a.xs;
a.xs = nullptr;
a.size = 0;
a.used = 0;
}
// Index an element of the array
int& index( Array& a, int n )
{
return a.xs[n];
}
// Resize an array (but only if necessary)
void resize( Array& a, int new_used )
{
if (new_used > a.size)
{
// A common but naive algorithm to increase capacity is to simply double it
// Also, our array defaults to a minimum of FIVE elements.
// There is no magic reason for 5; it is just small so you can see the array
// change size when you add the sixth element when running the example.
int new_size = a.size ? (a.size * 2) : 5;
// Create the new array
int* new_xs = newint[ new_size ];
// Copy the old array to the new array
for (int n = 0; n < a.used; n++)
new_xs[n] = a.xs[n];
// Delete the old array
delete[] a.xs;
// Update all our array data
a.xs = new_xs;
a.size = new_size;
}
a.used = new_used;
}
// Append a new element to the end of the array (resizing if necessary)
void append( Array& a, int value )
{
int n = a.used;
resize( a, a.used + 1 );
index( a, n ) = value;
}
// Print information about the array
void dumpArrayInfo( Array& a )
{
std::cout
<< "Number of elements allocated = " << a.size << "\n"
<< "Number of elements in use = " << a.used << "\n"
<< "Elements = { ";
if (a.used)
{
std::cout << a.xs[0];
for (int n = 1; n < a.used; n++)
std::cout << ", " << a.xs[n];
}
if (a.size - a.used)
{
if (a.used) std::cout << ", _";
else std::cout << "_";
for (int n = a.used+1; n < a.size; n++)
std::cout << ", _";
}
std::cout << " }\n";
}
// Demonstration
int main()
{
Array my_array;
// Don't forget to initialize
construct( my_array );
// Let's see what our initial state looks like
dumpArrayInfo( my_array );
// while (forever)
while (true)
{
std::cout << "\nEnter a number, or 'q' to quit: ";
int n;
std::cin >> n;
// Entering 'q' causes the last cin to fail. We'll notice that here and quit.
if (!std::cin) break;
// Add the new value to the end of the array.
append( my_array, n );
// While we're at it, let's set the very first element
// (it exists because we just appended!) to the same value.
index( my_array, 0 ) = n;
// And display the modifications we made
dumpArrayInfo( my_array );
}
// All done; clean up
destruct( my_array );
}
Notice also how I used the struct to keep the related information together. This is essentially the same as a class. All those convenient functions to manage the array could have been written as a class. This is exactly what a std::vector does!