Beispiellösung

Content

#ifndef ARRAY_HPP
#define ARRAY_HPP

#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <new>
#include <utility>

template<typename T>
class Array {
   public:
      Array() : size(0), data(nullptr) {
      }
      Array(std::size_t size) :
	 size(size),
	 data(size > 0?
	       static_cast<T*>(operator new(sizeof(T) * size))
	    :
	       nullptr) {
	 for (std::size_t index = 0; index < size; ++index) {
	    new (data + index) T();
	 }
      }
      Array(std::size_t size, const T& t) :
	 size(size),
	 data(size > 0?
	       static_cast<T*>(operator new(sizeof(T) * size))
	    :
	       nullptr) {
	 for (std::size_t index = 0; index < size; ++index) {
	    new (data + index) T(t);
	 }
      }
      Array(const Array& other) :
	    size(other.size),
	    data(size > 0?
	       static_cast<T*>(operator new(sizeof(T) * size))
	    :
	       nullptr) {
	 for (std::size_t index = 0; index < size; ++index) {
	    new (data + index) T(other.data[index]);
	 }
      }
      friend void swap(Array& a1, Array& a2) {
	 using std::swap;
	 swap(a1.size, a2.size);
	 swap(a1.data, a2.data);
      }
      Array(Array&& other) : Array() {
	 swap(*this, other);
      }
      ~Array() {
	 for (std::size_t index = 0; index < size; ++index) {
	    data[index].~T();
	 }
	 operator delete(data);
      }
      Array& operator=(Array other) {
	 swap(*this, other);
	 return *this;
      }
      std::size_t get_size() const {
	 return size;
      }
      T& operator()(std::size_t index) {
	 assert(index < size);
	 return data[index];
      }
      const T& operator()(std::size_t index) const {
	 assert(index < size);
	 return data[index];
      }
   private:
      std::size_t size;
      T* data;
};

#endif
#include <iostream>
#include "array.hpp"

int main() {
   Array<Array<double>> m(8);
   for (std::size_t i = 0; i < m.get_size(); ++i) {
      m(i) = Array<double>(m.get_size());
      for (std::size_t j = 0; j < m(i).get_size(); ++j) {
	 m(i)(j) = i + j;
      }
   }
   for (std::size_t i = 0; i < m.get_size(); ++i) {
      for (std::size_t j = 0; j < m(i).get_size(); ++j) {
	 std::cout << " " << m(i)(j);
      }
      std::cout << std::endl;
   }
}
theon$ g++ -Wall -o test-array test-array.cpp
theon$ valgrind ./test-array
==2039== Memcheck, a memory error detector
==2039== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2039== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==2039== Command: ./test-array
==2039== 
 0 1 2 3 4 5 6 7
 1 2 3 4 5 6 7 8
 2 3 4 5 6 7 8 9
 3 4 5 6 7 8 9 10
 4 5 6 7 8 9 10 11
 5 6 7 8 9 10 11 12
 6 7 8 9 10 11 12 13
 7 8 9 10 11 12 13 14
==2039== 
==2039== HEAP SUMMARY:
==2039==     in use at exit: 5,128 bytes in 1 blocks
==2039==   total heap usage: 11 allocs, 10 frees, 78,472 bytes allocated
==2039== 
==2039== LEAK SUMMARY:
==2039==    definitely lost: 0 bytes in 0 blocks
==2039==    indirectly lost: 0 bytes in 0 blocks
==2039==      possibly lost: 5,128 bytes in 1 blocks
==2039==    still reachable: 0 bytes in 0 blocks
==2039==         suppressed: 0 bytes in 0 blocks
==2039== Rerun with --leak-check=full to see details of leaked memory
==2039== 
==2039== For counts of detected and suppressed errors, rerun with: -v
==2039== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
theon$ 

Und hier der Test zum zweiten Teil der Aufgabe:

#include "array.hpp"

struct Test {
   Test(int i) : i(i) {
   }
   int i;
};

int main() {
   Array<Test> t(10, Test(42));
}
theon$ g++ -Wall -o test1 test1.cpp
theon$ valgrind ./test1
==2063== Memcheck, a memory error detector
==2063== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2063== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==2063== Command: ./test1
==2063== 
==2063== 
==2063== HEAP SUMMARY:
==2063==     in use at exit: 0 bytes in 0 blocks
==2063==   total heap usage: 2 allocs, 2 frees, 72,744 bytes allocated
==2063== 
==2063== All heap blocks were freed -- no leaks are possible
==2063== 
==2063== For counts of detected and suppressed errors, rerun with: -v
==2063== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
theon$