Каждый раз при использовании указателя его следует проверять на валидность. Например,
void print(int* ptr, const size_t length) {
if (ptr != nullptr) {
for (auto i = 0U; i < length; ++i) std::cout << ptr << ' ';
puts("");
}
}
Если передать в функцию указатель, которому после освобождения памяти не был присвоен nullptr, вы получите ошибку времени выполнения связанную с нарушением доступа для чтения либо записи.
void fn(int* ptr) {
if (ptr != nullptr) *ptr = 8; // ошибка записи
}
// TODO:
auto ptr = new int;
delete ptr;
fn(ptr); // передача в функцию «битого» указателя