#include #include // Finding three bugs // // The following program contains three bugs. // // The function print_array(...) should print // the elements of an array in the form // // {1, 2, 3, 4} // // An array with a capacity of zero should // be printed as // // {} // // If the pointer is nullptr, however, the // function should print nothing at all, // not even a newline. // // Find the three bugs, explain why they // are incorrect, and correct the program. // // Before looking at the hints, consider // what should happen in each of the // following cases: // // 1. A nonempty array. // 2. An array with a capacity of zero. // 3. A null pointer. // // Also check that all dynamically allocated // memory is eventually deallocated. // Function declarations int main(); void print_array( double const array[], std::size_t const capacity ); // Function definitions int main() { double data1[3]{ 4.55, 8.23, 1.23 }; double *data2{ new double[10]{ 27, 0, 1, 13, 25, 18, 16, 4, 28, 30 } }; print_array( data1, 3 ); print_array( data2, 10 ); // An empty array should print {}. print_array( data1, 0 ); // A null pointer should produce no output. print_array( nullptr, 0 ); return 0; } // Print the array in the form // // {1, 2, 3, 4} // // An empty array should print {}. // // If array is nullptr, print nothing. void print_array( double const array[], std::size_t const capacity ) { std::cout << "{"; std::cout << array[0]; for ( std::size_t k{ 1 }; k < capacity; ++k ) { std::cout << ", " << array[k]; } std::cout << "}" << std::endl; } // Hint: // // Consider the following questions: // // 1. If capacity is zero, is array[0] // a valid element? // // 2. If array is nullptr, can any // element be accessed? // // 3. Where is the memory allocated // for data2 deallocated? // // Remember that an array with zero // elements and a null pointer are // two different cases. // The three bugs: // // // BUG 1: Accessing an empty array // // std::cout << array[0]; // // This statement is executed even when // capacity is zero. // // An array with zero elements has no // valid indices, so accessing array[0] // causes undefined behavior. // // Only print the first element if // capacity is greater than zero. // // // BUG 2: Dereferencing a null pointer // // If array is nullptr, the function // attempts to access array[0]. // // This also causes undefined behavior. // // Since the specification says that // nothing should be printed for a null // pointer, return immediately: // // if ( array == nullptr ) { // return; // } // // This check must occur before printing // the opening brace. // // // BUG 3: A memory leak // // The array data2 is allocated using // // new double[10]{ ... } // // but it is never deallocated. // // Before main returns, add: // // delete[] data2; // // The brackets are required because // the memory was allocated using new[]. // Here is the corrected program: /* #include #include void print_array( double const array[], std::size_t const capacity ); int main() { double data1[3]{ 4.55, 8.23, 1.23 }; double *data2{ new double[10]{ 27, 0, 1, 13, 25, 18, 16, 4, 28, 30 } }; print_array( data1, 3 ); print_array( data2, 10 ); print_array( data1, 0 ); print_array( nullptr, 0 ); delete[] data2; data2 = nullptr; return 0; } void print_array( double const array[], std::size_t const capacity ) { if ( array == nullptr ) { return; } std::cout << "{"; if ( capacity > 0 ) { std::cout << array[0]; for ( std::size_t k{ 1 }; k < capacity; ++k ) { std::cout << ", " << array[k]; } } std::cout << "}" << std::endl; } */