so confused with this example.

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

thanks

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>

using namespace 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 = new int[ 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 = new int[ *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...
Thanks Duoas no problem I'll be right here =)

and line 49 was meant to be *size *= 2;

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
Last edited on
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.

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
#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 = new int[ 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!

Hope this helps.
Thanks a million Douas,If you were here I'd get you a beer haha,thanks for taking your time and breaking it down for me I'll study it now
guys just a question referring back to the first code I didn't know you could use a pointer as a return type?


int* growArray (int* p_values, int *size);


so basically that function is returning a memory address,I don't get it whats the point(no pun intended) of returning a pointer?
I didn't know you could use a pointer as a return type?

But you did use a pointer as a return type (lines 47,56).

so basically that function is returning a memory address

Correct. The address of the newly allocated array.

I don't get it whats the point(no pun intended) of returning a pointer?

If you didn't, how would main know where the newly allocated memory is? See line 24.

Topic archived. No new replies allowed.