SVN / public / code / vorlesung-06 / DynamicAllocationMain.cpp

Revision 8201
Date
Committerhb1003
Download
// Copyright 2026, University of Freiburg,
// Chair of Algorithms and Data Structures
// Author: Hannah Bast <bast@cs.uni-freiburg.de>

#include <cstdio>
#include <cstdlib>
#include <locale.h>

// Class for objects that manage their own piece of memory.
class ObjectWithAllocatedMemory {
public:
  // Construct with given number of bytes.
  explicit ObjectWithAllocatedMemory(size_t size) {
    bytes_ = new char[size];
    size_ = size;
    id_ = nextId_++;
    printf("Constructor for object #%d (size = %3zu, address = %'zu)\n", id_,
           size_, (size_t)bytes_);
  }

  // Copy constructor.
  ObjectWithAllocatedMemory(const ObjectWithAllocatedMemory &other) {
    // bytes_ = other.bytes_;
    bytes_ = new char[other.size_];
    for (size_t i = 0; i < other.size_; i++) {
      bytes_[i] = other.bytes_[i];
    }
    size_ = other.size_;
    id_ = nextId_++;
    printf("Copy constr for object #%d (size = %3zu, address = %'zu)\n", id_,
           size_, (size_t)bytes_);
  }

  // Copy assignment operator.
  //
  // NOTE: This does NOT create a new object, but overwrite the object.
  ObjectWithAllocatedMemory &operator=(const ObjectWithAllocatedMemory &other) {
    delete[] bytes_;
    bytes_ = new char[other.size_];
    for (size_t i = 0; i < other.size_; i++) {
      bytes_[i] = other.bytes_[i];
    }
    size_ = other.size_;
    printf("Copy assign for object #%d (size = %3zu, address = %'zu)\n", id_,
           size_, (size_t)bytes_);
    // This will be explained later or in V7.
    return *this;
  }

  // Destructor.
  ~ObjectWithAllocatedMemory() {
    delete[] bytes_;
    printf("Destructor  for object #%d (size = %3zu, address = %'zu)\n", id_,
           size_, (size_t)bytes_);
  }

  // Get the size.
  size_t size() const { return size_; }

private:
  // The bytes managed by this object.
  char *bytes_;
  // The number of bytes managed by this object.
  size_t size_;
  // The ID of this object.
  int id_;
  // The next ID for an object of this class.
  static int nextId_;
};

// The first ID of `ObjectWithAllocatedMemory` objects is 1.
int ObjectWithAllocatedMemory::nextId_ = 1;

// Function that does something with an `ObjectWithAllocatedMemory` object.
void doSomething(const ObjectWithAllocatedMemory &object) {
  printf("Size matters: %zu\n", object.size());
}

// Demonstrating stuff related to dynamic memory allocation for Vorlesung 6.
int main(int argc, char *argv[]) {
  // Set locale for thousand separators in `printf`.
  setlocale(LC_NUMERIC, "");

  // Create object that allocates 137 bytes for itself.
  ObjectWithAllocatedMemory object1(137);

  // Create another object that is copy of `object1`.
  ObjectWithAllocatedMemory object2(object1);

  // Assign one object to another.
  ObjectWithAllocatedMemory object3(42);
  object1 = object3;
  // Equivalent to: object1.operator=(object3);

  // Is this copy constructor (yes!) or copy assignment?
  ObjectWithAllocatedMemory object4 = object1;

  printf("\n");
  // doSomething(object3);
  // doSomething(1757);
  doSomething(ObjectWithAllocatedMemory(1757));
  // Equivalent to: doSomething(ObjectWithAllocatedMemory(1757));
  printf("\n");

  // // Parse command line arguments.
  // if (argc != 2) {
  //   printf("Usage: ./DynamicAllocationMain <number>\n");
  //   return 1;
  // }
  // const size_t n = atoi(argv[1]);

  // // Allocate n bytes and free them again.
  // // char bytes[n];
  // char *bytes = new char[n];
  // bytes[17] = 0;
  // delete[] bytes;
  // // delete[] bytes;
}