Класс String и вложенный вектор C ++ - PullRequest
0 голосов
/ 19 марта 2019

У меня проблемы с отладкой следующего кода.Однако вывод выглядит довольно странно.

Compilation successful
Running tests.....

empty vector passed
small sorted failed
input:
abc def ghi jkl mno pqrs tuv wxyz
expected output:
abc def ghi jkl mno pqrs tuv wxyz
actual output:
abc def�� ghi jkl mno pqrs tuv wxyz� 
--------------------------------------------------------------
small decreasing failed
input:
wxyz tuv pqrs mno jkl ghi def abc
expected output:
abc def ghi jkl mno pqrs tuv wxyz
actual output:
abc�� def ghi jkl mno pqrs tuv wxyz 
--------------------------------------------------------------
small randomised failed
input:
pqrs wxyz jkl tuv abc mno def ghi
expected output:
abc def ghi jkl mno pqrs tuv wxyz
actual output:
abc def ghi�� jkl mno pqrs tuv wxyz 
--------------------------------------------------------------
large failed
input:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod 
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim 
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea 
commodo consequat. Duis aute irure dolor in reprehenderit in voluptate       
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint 
occaecat cupidatat non proident, sunt in culpa qui officia deserunt 
mollit anim id est laborum.
expected output:
Duis Excepteur Lorem Ut ad adipiscing aliqua. aliquip amet, anim aute 
cillum commodo consectetur consequat. culpa cupidatat deserunt do dolor 
dolor dolore dolore ea eiusmod elit, enim esse est et eu ex 
exercitation fugiat id in in in incididunt ipsum irure labore laboris 
laborum. magna minim mollit nisi non nostrud nulla occaecat officia 
pariatur. proident, qui quis reprehenderit sed sint sit sunt tempor 
ullamco ut ut velit veniam, voluptate
actual output:
Duis� Excepteur���� Lorem Ut��� ad��� adipiscing aliqua. aliquip amet, 
anim� aute� cillum commodo consectetur�� consequat.��� culpa 
cupidatat���� deserunt����� do��� dolor dolore dolore dolor ea��� 
eiusmod elit, enim� esse� est�� et��� eu��� ex��� exercitation� fugiat 
id��� in��� in��� in��� incididunt��� ipsum irure labore laboris 
laborum.����� magna minim mollit nisi� non�� nostrud nulla 
occaecat����� officia pariatur.���� proident,���� qui�� quis� 
reprehenderit sed�� sint� sit sunt� tempor ullamco ut��� ut velit 
veniam, voluptate���� 
--------------------------------------------------------------

Я не знаю, почему программа делает такой странный вывод.Далее я включаю написанный код.

#include <algorithm>
#include <iostream>

template <class T>
class Vector
{
  public:
    // member types
    using value_type = T;
    using iterator = T*;
    using const_iterator = const T*;
    using reference = T&;
    using const_reference = const T&;

    // constructors
    Vector () : first {nullptr}, last {nullptr}, limit {nullptr} {}

    Vector (std::size_t size) : Vector (size, size) {}

    Vector (const Vector& vector) : Vector (vector.last - vector.first)
    {
        std::copy (vector.first, vector.last, first);
    }

    Vector (Vector&& vector) : Vector ()
    {
        swap (vector);
    }

    // deconstructor
    ~Vector ()
    {
        delete [] first;
    }

    // assignment
    Vector& operator = (const Vector& vector)
    {
        Vector copy {vector};
        swap (copy);
        return *this;
    }

    Vector& operator = (Vector&& vector)
    {
        swap (vector);
        return *this;
    }

    // iterators
    iterator begin ()
    {
      return first;
    }

    iterator end ()
    {
      return last;
    }

    const_iterator begin () const
    {
      return first;
    }

    const_iterator end () const
    {
     return last;
    }

    std::size_t size () const
    {
     return last - first;
    }

    // element access
    reference operator [] (std::size_t index)
    {
     return first[index];
    }

    const_reference operator [] (std::size_t index) const
    {
     return first[index];
    }

    // modifiers
    void swap (Vector& vector)
    {
        std::swap (first, vector.first);
        std::swap (last, vector.last);
        std::swap (limit, vector.limit);
    }

    void push_back (const value_type& value)
    {
        if (last == limit)
        {
            std::size_t size = last - first;
            Vector vector {size, size * 2 + 1};
            std::move (first, last, vector.first);
            swap (vector);
        }

        *last = value;
        ++last;
    }

    void pop_back (const value_type& value)
    {
        std::size_t size = last - first;
        std::size_t cap = limit - last;

      if (cap > 2 && size <= cap / 4)
        {
            Vector vector {size, size * 2 + 1};
            std::move (first, last, vector.first);
            swap (vector);
        }

    }

    void clear ()
    {
        last = first;
    }

  private:
    Vector (std::size_t size, std::size_t capacity) : first {new value_type[capacity]}, last {first + size}, limit {first + capacity} {}

    iterator first;
    iterator last;
    iterator limit;
};

template<typename T>
Vector<T> read ()
{
    Vector<T> vector;
    for (T value; std::cin >> value;) vector.push_back (value);
    return vector;
}

template<typename T>
void sort (T* begin, T* end)
{
  std::size_t size = end - begin;
    for (std::size_t index = 0; index != size; ++index)
    {
        auto minimum = index;
        for (auto comparand = minimum; comparand != size; ++comparand)
            if (*(begin + comparand) < *(begin + minimum))
              minimum = comparand;
        if (minimum != index)
          std::swap (*(begin + minimum), *(begin + index));
    }
}

template<typename T>
void write (T* begin, T* end)
{
   std::size_t size = end - begin;
    for (std::size_t index = 0; index != size; ++index)
        std::cout << *(begin + index) << ' ';
}

class String
{
    public:
    // constructors
    String () {}

    // iterators
    char* begin ()
    {
      return string.begin();
    }

    char* end ()
    {
      return string.end();
    }

    const char* begin () const
    {
      return string.begin();
    }

    const char* end () const
    {
        return string.end();
    }

    // modifiers
    void clear ()
    {
      string.clear();
    }

    String& operator += (char character)
    {
            string.push_back(character);
    }

  private:
  Vector<char> string;
  std::size_t size;
};

bool operator < (const String& a, const String& b)
{
    return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
}

std::ostream& operator << (std::ostream& os, const String& string)
{
  os << string.begin();
    return os;
}

std::istream& operator >> (std::istream& is, String& string)
{
    string.clear (); 
    while (is.good () && std::isspace (is.peek ())) is.ignore ();
    while (is.good () && std::isgraph (is.peek ())) string += is.get ();
    if (string.begin () == string.end ()) is.setstate (is.failbit);
    return is;
}


int main ()
{
    auto vector = read<String> ();
    sort (vector.begin (), vector.end ());
    write (vector.begin (), vector.end ());
}

Программа должна взять из ввода некоторые строки, отсортировать их лексикографически и затем распечатать.Тем не менее, я думаю, что моя ошибка - функция перегрузки оператора для строки.Но не знаю, как улучшить функцию.

Спасибо за любую помощь :)


-EDIT-

Я нашелошибка в

std::ostream& operator << (std::ostream& os, const String& string)

Правильная функция будет

std::ostream& operator << (std::ostream& os, const String& string)
{
  for(auto x : string)
  os << x;
  return os;
}

Благодаря всей предоставленной помощи.:)

Ответы [ 3 ]

1 голос
/ 19 марта 2019

Не уверен, является ли это причиной наблюдаемого результата, но это определенно вызывает неопределенное поведение при вызове метода. Ваш Vector::end() это:

const_iterator end () const {  
    last; 
}

Этот метод ничего не возвращает.

Обратите внимание, что приличный компилятор должен предупредить вас о том, что статут не имеет никакого эффекта.

0 голосов
/ 19 марта 2019

Я закрываю вопрос, потому что я нашел ответ. Спасибо всем, кто помог мне.

0 голосов
/ 19 марта 2019

В вашем вопросе нет кода для воспроизведения проблемы, с которой вы столкнулись.

Пара обнаруженных мной проблем:

  1. Конструктор копирования выделяет память, а затем копирует элементы.Если копирование выбрасывает, деструктор никогда не запускается и он теряет память.
  2. Закрытый конструктор размещения использует new, который вызывает конструкторы элементов по умолчанию.Это бесполезное усилие, если следующая вещь, которую вы делаете, это перезаписывает элементы в конструкторе копирования.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...