teaching machines

CS 330 Lecture 32 – Garbage Collection

April 24, 2013 by . Filed under cs330, lectures, spring 2013.

Agenda

TODO

Code

FasterString.cpp

#include <cstring>
#include <iostream>
#include "SmartPointer.h"

class FasterString {
  public:
    FasterString();
    FasterString(const char *s);

    ~FasterString();

    int GetLength() const;

    char& operator[](int i);
    const char& operator[](int i) const;
    bool operator==(const FasterString& other) const;

    FasterString operator+(const FasterString& other) const;
    FasterString operator*(int n) const;
    FasterString &operator+=(const FasterString& other);

  private:
    char *text;
    int length;
};

/* ------------------------------------------------------------------------- */

FasterString::FasterString() :
  length(0),
  text(new char[0]) {
}

/* ------------------------------------------------------------------------- */

FasterString::FasterString(const char *s) :
  length(strlen(s)) {
  text = new char[length]; 
  memcpy(text, s, sizeof(char) * length);
}

/* ------------------------------------------------------------------------- */

FasterString::~FasterString() {
  std::cout << "in dtor" << std::endl;
  delete[] text;  
}

/* ------------------------------------------------------------------------- */

char& FasterString::operator[](int i) {
  return text[i];
}

/* ------------------------------------------------------------------------- */

const char& FasterString::operator[](int i) const {
  return text[i];
}

/* ------------------------------------------------------------------------- */

int FasterString::GetLength() const {
  return length;
}

/* ------------------------------------------------------------------------- */

std::ostream& operator<<(std::ostream& out, const FasterString &s) {
  for (int i = 0; i < s.GetLength(); ++i) {
    out << s[i];
  }
  return out;
}

/* ------------------------------------------------------------------------- */

FasterString FasterString::operator+(const FasterString& other) const {
  FasterString joined;
  joined.length = GetLength() + other.GetLength();
  delete[] joined.text;
  joined.text = new char[joined.length];

  memcpy(joined.text, text, GetLength());
  memcpy(joined.text + GetLength(), other.text, other.GetLength());

  return joined;
}

/* ------------------------------------------------------------------------- */

bool FasterString::operator==(const FasterString& other) const {
  if (other.GetLength() != GetLength()) {
    return false;
  }

  for (int i = 0; i < GetLength(); ++i) {
    if ((*this)[i] != other[i]) {
      return false;
    }
  }  

  return true;
}

/* ------------------------------------------------------------------------- */

FasterString FasterString::operator*(int n) const {
  FasterString joined;
  joined.length = GetLength() * n;
  delete[] joined.text;
  joined.text = new char[joined.length];

  for (int i = 0; i < n; ++i) {
    memcpy(joined.text + i * GetLength(), text, sizeof(char) * GetLength());
  }

  return joined;
}

/* ------------------------------------------------------------------------- */

FasterString &FasterString::operator+=(const FasterString& other) {
  int new_length = GetLength() + other.GetLength();
  char *new_text = new char[new_length];
  memcpy(new_text, text, sizeof(char) * GetLength());
  memcpy(new_text + GetLength(), other.text, sizeof(char) * other.GetLength());
  delete[] text;
  text = new_text;
  length = new_length;
  return *this;
}

/* ------------------------------------------------------------------------- */

int main(int argc, char **argv) {
  {
    SmartPointer<FasterString> s(new FasterString("Greasy grimy gopher "));
    std::cout << "*s: " << *s << std::endl;
    /* delete s; */
  }
  std::cout << "after block" << std::endl;
  /* s.Destroy(); */
  /* std::cout << "s: " << s << std::endl; */
  /* std::cout << "s + FasterString(\"guts\"): " << s + FasterString("guts") << std::endl; */
  /* std::cout << "FasterString(\"foo \") * 5: " << FasterString("foo ") * 5 << std::endl; */
  /* std::cout << "FasterString(\"a\") + FasterString(\"b\") == FasterString(\"ab\"): " << (FasterString("a") + FasterString("b") == FasterString("ab")) << std::endl; */
  /* s += "horns"; */
  /* std::cout << "s: " << s << std::endl; */

  return 0;
}

SmartPointer.h

#ifndef SMARTPOINTER_H
#define SMARTPOINTER_H

template<typename T> class SmartPointer {
  public:
    SmartPointer(T *ptr);
    SmartPointer(const SmartPointer<T> &other);
    ~SmartPointer();

    SmartPointer<T> &operator=(const SmartPointer<T> &other);

    T *operator->();
    T &operator*();

  private:
    void Depatron();

    T *ptr;
    int *nPatrons;
};

template<typename T>
SmartPointer<T>::SmartPointer(T *ptr) :
  ptr(ptr),
  nPatrons(new int(1)) {
}

template<typename T>
SmartPointer<T>::SmartPointer(const SmartPointer<T> &other) :
  ptr(other.ptr),
  nPatrons(other.nPatrons) {
  ++(*nPatrons);
}

template<typename T>
SmartPointer<T>::~SmartPointer() {
  Depatron();  
}

template<typename T>
SmartPointer<T> &SmartPointer<T>::operator=(const SmartPointer<T> &other) {
  if (&other != this) {
    Depatron();
    ptr = other.ptr;  
    nPatrons = other.nPatrons;  
    ++(*nPatrons);
  }

  return *this;
}

template<typename T>
void SmartPointer<T>::Depatron() {
  --(*nPatrons); 
  if (*nPatrons == 0) {
    delete ptr;
    ptr = NULL;
    delete nPatrons;
    nPatrons = NULL;
  }
}

template<typename T>
T *SmartPointer<T>::operator->() {
  return ptr;
}

template<typename T>
T &SmartPointer<T>::operator*() {
  return *ptr;  
}

#endif

Haiku

Someday you’ll be gone
Have a non-zero counter
Just one is enough