Dynamic Memory Allocation

Instructions:

Make sure you use the specified function prototypes. Please feel free to introduce additional subroutines (i.e., functions) to help you implement the required functions.

Submit three files as described below. Please name your files as specified to avoid unnecessary complications.

Use pointers to manage a dynamic array of integers, including

memory allocation & value initialization

Resizing

Changing and reordering the contents of an array

memorydeallocation

Learn the difference between passing a pointer to a function by value vs. by reference
Learn to use pointers to functions to make a function more powerful and template-like.
Learn to include multiple files in a C++ project by distributing the source codes accordingly to different files.

  1. Your project will include the following three files:A header file: dynamicArray.h that includes a list of function prototypes as enumerated in the next section.
    An implementation file: dynamicArray.cpp that implements the functions declared in the header file.
    A test driver file: dynamicArray-main.cpp that includes the main() function so that you can test all the functions you’ve implemented above.
  2. The header file dynamicArray.h will include the following list of functions:constructing a dynamic array of the specified size and initializing the i-th array element to i*i
    int * array_constructor(int *  &intPtr, int&size );Specifically, the above function allocates space to intPtr and uses it to manage a dynamic array of size integers. Use proper exception handling to make sure that the allocation is successful. Then initialize the value of the i-th element to i*i. The function returns a pointer pointing to the new array. To avoid memory leakage, you should check whether intPtr already has a valid pointee when being passed into this function. If the answer is yes, you would want to first deallocate the space occupied by its pointee.As an example, after invoking this function array_constructor( myArray, size=5); in a different function, the content of myArray will bemyArray[0]=0
    myArray[1]=1
    myArray[2]=4
    myArray[3]=9
    myArray[4]=16
    resizing a dynamic array pointed to by intPtr, where the new size can be smaller or larger than the array’s current size
    int * array_resize(int * &intPtr, int&currSize, int&newSize);
    You will need to first make sure both curSize and newSize have valid values, i.e., positive integers.

Then consider the following three scenarios:

currSize==newSize or newSize<0: do nothing
currSize>newSize: the array’s size is reduced to newSize. Furthermore, its content is reduced to its first newSize elements.
currSize<newSize: the array’s size is increased to newSize. The content of the array will be expanded by inserting at the end as many elements as needed to reach newSize. Furthermore, initialize each of the new elements to i*i, where i is the index of the element.
As an example, after invoking this function array_resize( myArray, currSize, newSize); (where currSize=5, newSize=9), the content of myArray will be changed to

myArray[0]=0
myArray[1]=1
myArray[2]=4
myArray[3]=9
myArray[4]=16
myArray[5]=25
myArray[6]=36
myArray[7]=49
myArray[8]=64
Later, another invocation array_resize( myArray, currSize, newSize);(where currSize=9, newSize=2) will change the content of myArray to:

myArray[0]=0
myArray[1]=1
deallocating the memory space occupied by the dynamic array intPtr. Please make sure you check whether this array actually exists. After you finish deallocating the array space, make sure to assign nullptr to the pointer.
voidarray_destructor(int * &intPtr);
Randomizing the content of the dynamic array intPtr by calling the srand() and rand() functions (see zyBook section 2.19).
voidarray_set(int* &intPtr, int&size);
Specifically, after having set a seed value using the srand( time(0) ) function. Then invoke the rand() to assign each element in the array a random value.

As an example, after invoking array_set( myArray, currSize); (where currSize=9) in a different function, myArray will look like:

myArray[0]=415960052
myArray[1]=981322979
myArray[2]=420899093
myArray[3]=239922833
myArray[4]=1556248812
myArray[5]=1670446471
myArray[6]=1140120866
myArray[7]=14812681
myArray[8]=1996110162
Passing a pointer to functions to a sorting function mysort() so that this function can either sort an array in ascending or descending order. Please modify the insertionSort() you implemented in the last coding lab to sort an integer array.

void mysort( int* &intPtr, int size, bool (* comp)(int&, int&) );
To do this, please include the following two boolean functions for integer comparison in your header file:

boolmy_less_equal(int& x, int& y);   //return true if x<=y, false otherwise.
boolmy_greater_equal(int& x, int& y ); //return true if x>=y, false otherwise.

Now, if one calls mysort(myArray, size, my_less_equal); in another function, the content in myArray will be sorted in ascending order; calling mysort( myArray, size, my_greater_equal); will sort myArray in descending order.

3. The implementation file dynamicArray.cpp will implement all the functions declared in the above dynamicArray.h header file.

4. A test driver file: dynamicArray-main.cpp that includes the main() function so that you can test all the functions you’ve declared and implemented in the above two files. 

Solution

 dynamicArray.cpp

#include “dynamicArray.h”

#include <iostream>

#include <cstdlib>

#include <ctime>

int *array_constructor(int *&intPtr, int&size) {

// parameter checking, if size is negative, do not change the array.

if (size <= 0) {

std::cerr<< “array size is negative!” <<std::endl;

returnintPtr;

}

if (intPtr != nullptr) {

// free the array

delete[] intPtr;

intPtr = nullptr;

}

intPtr = new int[size];

if (intPtr == nullptr) {

std::cerr<< “could not allocate array!” <<std::endl;

} else {

// initialize the i-th item in the array to i*i.

for (int i = 0; i < size; i++) {

intPtr[i] = i * i;

}

}

returnintPtr;

}

int *array_resize(int *&intPtr, int&currSize, int&newSize) {

// parameter checking.

if (intPtr == nullptr || currSize == newSize || newSize< 0 || currSize< 0) {

returnintPtr;

}

// create a new array to hold the resized array

int *newArr = new int[newSize];

if (newArr == nullptr) {

std::cerr<< “could not alloate new array!” <<std::endl;

returnintPtr;

}

for (int i = 0; i <currSize&& i <newSize; i++) {

newArr[i] = intPtr[i];

}

for (int i = currSize; i <newSize; i++) {

newArr[i] = i * i;

}

// deallocate the original array and use the new array

delete[] intPtr;

intPtr = newArr;

returnintPtr;

}

voidarray_destructor(int *&intPtr) {

if (intPtr != nullptr) {

delete[] intPtr;

intPtr = nullptr;

}

}

voidarray_set(int *&intPtr, int&size) {

// setup the random seed

srand(time(0));

if (intPtr != nullptr) {

// set random numbers in the array

for (int i = 0; i < size; i++) {

intPtr[i] = rand();

}

}

}

voidmysort( int* &intPtr, int size, bool (*comp)(int&, int&) ) {

if (intPtr != nullptr) {

for (int i = 1; i < size; i++) {

int value = intPtr[i];

// find the location to insert the value

int k = i – 1;

while (k >= 0 && comp(value, intPtr[k])) {

intPtr[k + 1] = intPtr[k];

k –;

}

// insert the new value

intPtr[k + 1] = value;

}

}

}

boolmy_less_equal(int& x, int& y) {

return x <= y;

}

boolmy_greater_equal(int& x, int& y ) {

return x >= y;

} 

dynamicArray.h

 #ifndef DYNAMIC_ARRAY_H_

#define DYNAMIC_ARRAY_H_

// constructing a dynamic array of the specified size and initializing the i-th array element to i*i

int *array_constructor(int *&intPtr, int&size);

// resizing a dynamic array pointed to by intPtr, where the new size can be smaller or larger than the array’s current size

int *array_resize(int *&intPtr, int&currSize, int&newSize);

voidarray_destructor(int *&intPtr);

// Randomizing the content of the dynamic array intPtr by calling the srand() and rand() functions (see zyBook section 2.19).

voidarray_set(int *&intPtr, int&size);

// insertion sort the array

voidmysort( int* &intPtr, int size, bool (* comp)(int&, int&) );

boolmy_less_equal(int& x, int& y);   //return true if x<=y, false otherwise.

boolmy_greater_equal(int& x, int& y ); //return true if x>=y, false otherwise.

#endif 

dynamicArray-main.cpp

#include “dynamicArray.h”

#include <iostream>

using namespace std;

int main() {

// test the functions in dynamicArray

int *intPtr = nullptr;

int size = 5;

intPtr = array_constructor(intPtr, size);

for (int i = 0; i < size; i++) {

cout<<intPtr[i] << ” “;

}

cout<<endl;

intoldsize = size;

size = 9;

intPtr = array_resize(intPtr, oldsize, size); // resize the array with larger size

for (int i = 0; i < size; i++) {

cout<<intPtr[i] << ” “;

}

cout<<endl;

oldsize = size;

size = 2;

intPtr = array_resize(intPtr, oldsize, size); // resize the array with smaller size

for (int i = 0; i < size; i++) {

cout<<intPtr[i] << ” “;

}

cout<<endl;

// random set the array

size = 5;

array_set(intPtr, size);

for (int i = 0; i < size; i++) {

cout<<intPtr[i] << ” “;

}

cout<<endl;

// sort the array increasingly

mysort(intPtr, size, my_less_equal);

for (int i = 0; i < size; i++) {

cout<<intPtr[i] << ” “;

}

cout<<endl;

// random set the array

size = 5;

array_set(intPtr, size);

// sort the array decreasingly

mysort(intPtr, size, my_greater_equal);

for (int i = 0; i < size; i++) {

cout<<intPtr[i] << ” “;

}

cout<<endl;

// deallocate the array multiple times should not generate error.

array_destructor(intPtr);

array_destructor(intPtr);

return 0;

}