Beispiellösung
Content |
#ifndef INTEGER_SEQUENCE_HPP #define INTEGER_SEQUENCE_HPP #include <cassert> #include <cstdlib> #include <new> class IntegerSequence { public: IntegerSequence() : data(nullptr), size(0), allocated(0) { } IntegerSequence(const IntegerSequence& other) : data( other.data? static_cast<int*>(std::malloc(other.allocated * sizeof(int))) : nullptr ), size(other.size), allocated(other.allocated) { if (size > 0 && !data) { throw std::bad_alloc(); } for (std::size_t i = 0; i < size; ++i) { data[i] = other.data[i]; } } ~IntegerSequence() { std::free(data); } IntegerSequence& operator=(const IntegerSequence& other) { if (other.size > allocated) { int* newdata = static_cast<int*>(std::realloc(data, other.allocated * sizeof(int))); if (!newdata) { throw std::bad_alloc(); } data = newdata; allocated = other.allocated; } size = other.size; for (std::size_t i = 0; i < size; ++i) { data[i] = other.data[i]; } return *this; } void add(int value) { if (size == allocated) { std::size_t newsize = allocated * 2 + 8; int* newdata = static_cast<int*>(std::realloc(data, newsize * sizeof(int))); if (!newdata) { throw std::bad_alloc(); } data = newdata; allocated = newsize; } data[size++] = value; } std::size_t length() const { return size; } int& operator()(std::size_t index) { assert(index < size); return data[index]; } const int& operator()(std::size_t index) const { assert(index < size); return data[index]; } private: int* data; std::size_t size; std::size_t allocated; }; #endif
#include <iostream> #include "IntegerSequence.hpp" void print(const IntegerSequence& is) { for (std::size_t i = 0; i < is.length(); ++i) { std::cout << " " << is(i); } std::cout << std::endl; } int main() { IntegerSequence iseq; int value; while (std::cin >> value) { iseq.add(value); } std::cout << "iseq: "; print(iseq); IntegerSequence iseq2 = iseq; // copy constructor iseq2.add(42); std::cout << "iseq2: "; print(iseq2); iseq = iseq2; // copy it back std::cout << "iseq: "; print(iseq); }
theon$ g++ -Wall -o test_is test_is.cpp theon$ echo 1 2 3 4 5 6 7 8 | valgrind ./test_is ==22592== Memcheck, a memory error detector ==22592== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==22592== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info ==22592== Command: ./test_is ==22592== --22592-- WARNING: Serious error when reading debug info --22592-- When reading debug info from /lib/amd64/ld.so.1: --22592-- Can't make sense of .data section mapping iseq: 1 2 3 4 5 6 7 8 iseq2: 1 2 3 4 5 6 7 8 42 iseq: 1 2 3 4 5 6 7 8 42 ==22592== ==22592== HEAP SUMMARY: ==22592== in use at exit: 10,256 bytes in 2 blocks ==22592== total heap usage: 7 allocs, 5 frees, 83,216 bytes allocated ==22592== ==22592== LEAK SUMMARY: ==22592== definitely lost: 0 bytes in 0 blocks ==22592== indirectly lost: 0 bytes in 0 blocks ==22592== possibly lost: 10,256 bytes in 2 blocks ==22592== still reachable: 0 bytes in 0 blocks ==22592== suppressed: 0 bytes in 0 blocks ==22592== Rerun with --leak-check=full to see details of leaked memory ==22592== ==22592== For lists of detected and suppressed errors, rerun with: -s ==22592== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) theon$