#include // std::cout /* * This is an example for the memory bug known as a dangling pointer. * * We store the address of data items, which in the beginning is a valid * address, pointing to legitimate actual data. But then, the data are * deallocated, while the pointer keeps remembering the old address. * * If the pointer is dereferenced, it can lead to bogus data being used, * or it can in principle even lead to a segmentation fault. * * Explain: How is this the case in the present code? Where are the data * being allocated, and where do we continue keeping a dangling pointer? * Note that here, there is no manual memory allocation or deallocation. */ /* * class used to walk through an array and * retain pointers to the smallest and greatest entry */ class Registry { public: Registry() = default; int get_greatest() { if(this->greatest == nullptr) return 0; else return *(this->greatest); } int get_smallest() { if(this->smallest == nullptr) return 0; else return *(this->smallest); } void read_array(int size, int* data) { if(size < 1) return; greatest = &data[0]; smallest = &data[0]; for(int i = 0; i < size; i++) if(data[i] > *greatest) greatest = &data[i]; else if(data[i] < *smallest) smallest = &data[i]; } private: int* greatest = nullptr; // non-owning pointer to greatest value on record int* smallest = nullptr; // non-owning pointer to greatest value on record }; /* * use unnamed namespace for constants that we do not need elsewhere */ namespace { constexpr int array_size = 7; constexpr int divisor = 11; constexpr int offset = 13; } /* * create an array with some data and hand it over to *r for analysis */ void crunch_numbers(Registry* r) { int dataset[array_size]{}; for(int i = 0; i < array_size; i++) dataset[i] = ((offset+i)*(offset+i)) % divisor; r->read_array(array_size, dataset); std::cout << "smallest: " << r->get_smallest() << ",\tgreatest: " << r->get_greatest() << "\n"; } int main() { Registry r{}; crunch_numbers(&r); /* * Repeat the output statement from above. * Something goes wrong. Why? What happened? */ std::cout << "\nsmallest: " << r.get_smallest() << ",\tgreatest: " << r.get_greatest() << "\n"; }