#define ALLOW_INSTRUCTOR_CODE /*************************************************************************** *************************************************************************** ****** BEFORE BEGINNING OR TURNING IN THIS EXERCISE IT IS EXTREMELY ****** ****** IMPORTANT THAT YOU READ, FULLY UNDERSTAND, AND ADHERE TO THE ****** ****** REQUIREMENTS STATED IN THE DOCUMENT TITLED, "ASSIGNMENT ****** ****** SUBMISSION REQUIREMENTS", DOWNLOADABLE FROM THE COURSE WEB ****** ****** SITE. ****** *************************************************************************** **************************************************************************/ /*************************************************************************** ************* C/C++ Programming 2: Assignment 5 - Exercise 2 ************* ********* BEGIN EXERCISE REQUIREMENT - THIS MUST BE A "C" PROGRAM ********* *************************************************************************** (3 points) Any call to a standard memory allocation function reserves a region of storage not necessarily contiguous with that allocated by any previous call. Such was the case with the CreateInt2D function discussed in "Advanced C/C++ Notes" section 14. This function was wasteful in that it did multiple dynamic memory allocations, plus a custom FreeInt2D function was necessary to free the array. Even worse, the array it created could not be accessed linearly. Efficiency and versatility can enhanced by simply pre-calculating the total amount of memory needed, then allocating it all at once. The advantages of doing this are: 1. The elements of the array can be accessed linearly. 2. A custom FreeInt2D function is not needed; the standard library free function can be used instead. 3. There is a reduced likelihood of cache misses when random array elements are accessed. Disadvantages are: 1. Data type alignment problems are possible when multiple data types are mixed (This can be solved, but ignore it for this exercise.). 2. A large region of contiguous memory may not be available, whereas the same amount might be available in smaller increments. Rewrite function CreateInt2D, calling it CreateStruct2D instead. It must be similar to CreateInt2D with the following exceptions: * CreateStruct2D creates an array for type "struct test" rather than type int. * CreateStruct2D makes only one memory allocation call to get all needed memory, then initializes the pointer portion of it as necessary. *************************************************************************** ************************ END EXERCISE REQUIREMENT ************************* **************************************************************************/ /* ************** Do not change the following structure typedef ************** **************** in any way without instructor permission. **************** *** You do not need to understand the details of my code to write yours! ** */ #ifdef ALLOW_INSTRUCTOR_CODE typedef struct test { char charObj; short shortObj; long longObj; double doubleObj; } TEST; #endif /*************************************************************************** * BEFORE PRINTING THIS ASSIGNMENT TO TURN IN, DELETE THIS COMMENT AND * EVERYTHING ABOVE IT. **************************************************************************/ /* * TODO: * REPLACE THIS COMMENT WITH YOUR TITLE BLOCK. */ /* * TODO: * REPLACE THIS COMMENT WITH YOUR C CODE, PLUS ANYTHING NECESSARY TO * SUPPORT MY TEST CODE BELOW. DO NOT INCLUDE ANY UNNEEDED HEADER FILES! */ /*************************************************************************** * BEFORE PRINTING THIS ASSIGNMENT TO TURN IN, DELETE THIS COMMENT AND * EVERYTHING BELOW IT. **************************************************************************/ /* ***** Change nothing below this comment without instructor permission. **** * Everything that follows was written to help test/verify your code. You * do not need to understand the details of my code to write yours! */ #ifdef ALLOW_INSTRUCTOR_CODE int TestCreateStruct2D(TEST **pps, int dim0, int dim1); int main(void) { TEST **pps; /* Create a 2D array dynamically. */ pps = CreateStruct2D(5, 10); /* Test it and print the results. */ printf("CreateStruct2D %s\n", TestCreateStruct2D(pps, 5, 10) ? "succeeded" : "failed"); /* Free the array. */ free(pps); /* Create another 2D array dynamically. */ pps = CreateStruct2D(25, 17); /* Test it and print the results. */ printf("CreateStruct2D %s\n", TestCreateStruct2D(pps, 25, 17) ? "succeeded" : "failed"); /* Free the array. */ free(pps); return EXIT_SUCCESS; } int TestCreateStruct2D(TEST **pps, int dim0, int dim1) { int i, j; TEST test, *ps; /* Fill up the array with known values using 2D syntax. */ test.charObj = 0; test.shortObj = 100; test.longObj = 10000L; test.doubleObj = 100000.0; for (i = 0; i < dim0; ++i) for (j = 0; j < dim1; ++j) { pps[i][j].charObj = test.charObj++; pps[i][j].shortObj = test.shortObj++; pps[i][j].longObj = test.longObj++; pps[i][j].doubleObj = test.doubleObj++; } /* Verify the stored values using a compact pointer. */ test.charObj = 0; test.shortObj = 100; test.longObj = 10000L; test.doubleObj = 100000.0; for (ps = (TEST *)(pps + dim0); ps < (TEST *)&pps[dim0 - 1][dim1]; ++ps) if (ps->charObj != test.charObj++ || ps->shortObj != test.shortObj++ || ps->longObj != test.longObj++ || ps->doubleObj != test.doubleObj++ ) break; /* Return a success or an error code. */ if (ps < (TEST *)&pps[dim0 - 1][dim1]) return 0; /* failure return */ else return 1; /* success return */ } #endif