/*
 * Copyright ©2026 Soham Pardeshi. All rights reserved.
 * Permission is hereby granted to students registered for University of
 * Washington CSE 333 for use solely during Summer Quarter 2026 for
 * purposes of the course. No other use, copying, distribution, or
 * modification is permitted without prior written consent. Copyrights
 * for third-party components of this work must be honored. Instructors
 * interested in reusing these course materials should contact the author.
 */

#include <iostream>   // for std::cout, std::endl
#include <cstdlib>    // for EXIT_SUCCESS

using std::cout;
using std::endl;

// C++ heap allocation with new / delete.  Unlike malloc/free, new and delete
// are typed (no cast, no sizeof) and new THROWS std::bad_alloc on failure --
// it never returns NULL, so there is no NULL check to write.

int main(int argc, char** argv) {
  // One value on the heap.
  int* n = new int(333);  // allocate an int, initialized to 333
  int* m = new int;       // allocate an int, UNINITIALIZED
  delete n;               // give the memory back
  delete m;

  // An array on the heap: new[] pairs with delete[], not plain delete.
  int* a = new int[3]{6, 7, 8};  // C++11 brace initialization

  // Shallow copy: copies the POINTER, not the values.  Now a and b share one
  // buffer, so deleting both would be a DOUBLE FREE.
  //   int* b = a;   // aliasing! delete[] a; delete[] b; -> double free

  // Deep copy: b gets its OWN buffer, so each pointer owns and frees one block.
  int* b = new int[3];
  for (int i = 0; i < 3; i++) {
    b[i] = a[i];  // copy the values across
  }

  delete[] a;
  delete[] b;     // two arrays, two clean deletes

  // After delete, a pointer is DANGLING; using it is undefined behavior.
  a = nullptr;    // habit: null it out so misuse crashes loudly

  return EXIT_SUCCESS;
}

// Compile with:
//   g++ -Wall -g -std=c++17 -o heap heap.cc