Создать векторный класс, который удваивает размер памяти, когда достигнут конец? - PullRequest
0 голосов
/ 08 апреля 2019

Как у всех, у меня проблема довольно двусмысленная. Я думаю, что это двусмысленно в том смысле, что это дано моим инструктором, как это без дальнейшего объяснения. Я создал простой векторный класс, который стимулирует векторы. Исходя из этого, я хочу доработать и добавить новые функциональные возможности. По словам моего инструктора: Используйте простой вектор, который вы создали ранее, чтобы создать два других более сложных вектора с

1) Распределение памяти, которое удваивает размер памяти, когда достигнут конец, и 1/2 памяти, когда размер достигает 1/4.

2) Реализовано с помощью единственно связанного списка.

Это буквально все, с чего я должен начать. Я довольно новичок в кодировании. На этой заметке мне трудно подойти к этой проблеме, либо потому, что инструкции недостаточно, либо я недостаточно знаком с c ++. Может кто-нибудь дать мне несколько советов о том, как подойти к этой проблеме? (Что, черт возьми, я должен делать?) Любые предложения с благодарностью:)

Вот векторный класс, который я создал:

SimpleVector.h:

#ifndef SIMPLEVECTOR_H
#define SIMPLEVECTOR_H
#include <iostream>
#include <new>       // Needed for bad_alloc exception
#include <cstdlib>   // Needed for the exit function
using namespace std;

template <class T>
class SimpleVector
{
private:
   T *aptr;          // To point to the allocated array
   int arraySize;    // Number of elements in the array
   void memError();  // Handles memory allocation errors
   void subError();  // Handles subscripts out of range

public:
   // Default constructor
   SimpleVector()
      { aptr = 0; arraySize = 0;}

   // Constructor declaration
   SimpleVector(int);

   // Copy constructor declaration
   SimpleVector(const SimpleVector &);

   // Destructor declaration
   ~SimpleVector();

   // Accessor to return the array size
   int size() const
      { return arraySize; }

   // Accessor to return a specific element
   T getElementAt(int position);

   // Overloaded [] operator declaration
   T &operator[](const int &);

   void push_back(T);

   T pop_back();

   void push_front(T);

   T pop_front();
};

//***********************************************************
// Constructor for SimpleVector class. Sets the size of the *
// array and allocates memory for it.                       *
//***********************************************************

template <class T>
SimpleVector<T>::SimpleVector(int s)
{
   arraySize = s;
   // Allocate memory for the array.
   try
   {
      aptr = new T [s];
   }
   catch (bad_alloc)
   {
      memError();
   }

   // Initialize the array.
   for (int count = 0; count < arraySize; count++)
      *(aptr + count) = 0;
}

//*******************************************
// Copy Constructor for SimpleVector class. *
//*******************************************

template <class T>
SimpleVector<T>::SimpleVector(const SimpleVector &obj)
{
   // Copy the array size.
   arraySize = obj.arraySize;

   // Allocate memory for the array.
   aptr = new T [arraySize];
   if (aptr == 0)
      memError();

   // Copy the elements of obj's array.
   for(int count = 0; count < arraySize; count++)
      *(aptr + count) = *(obj.aptr + count);
}

//**************************************
// Destructor for SimpleVector class.  *
//**************************************

template <class T>
SimpleVector<T>::~SimpleVector()
{
   if (arraySize > 0)
      delete [] aptr;
}

//*******************************************************
// memError function. Displays an error message and     *
// terminates the program when memory allocation fails. *
//*******************************************************

template <class T>
void SimpleVector<T>::memError()
{
   cout << "ERROR:Cannot allocate memory.\n";
   exit(EXIT_FAILURE);
}

//***********************************************************
// subError function. Displays an error message and         *
// terminates the program when a subscript is out of range. *
//***********************************************************

template <class T>
void SimpleVector<T>::subError()
{
   cout << "ERROR: Subscript out of range.\n";
   exit(EXIT_FAILURE);
}

//*******************************************************
// getElementAt function. The argument is a subscript.  *
// This function returns the value stored at the sub-   *
// cript in the array.                                  *
//*******************************************************

template <class T>
T SimpleVector<T>::getElementAt(int sub)
{
   if (sub < 0 || sub >= arraySize)
      subError();
   return aptr[sub];
}

//*******************************************************
// Overloaded [] operator. The argument is a subscript. *
// This function returns a reference to the element     *
// in the array indexed by the subscript.               *
//*******************************************************

template <class T>
T &SimpleVector<T>::operator[](const int &sub)
{
   if (sub < 0 || sub >= arraySize)
      subError();
   return aptr[sub];
}

template <class T>
void SimpleVector<T>::push_front(T val){
   // Allocate memory for the array.
   try {
        T *new_Aptr = new T[arraySize + 1];

        for (int i = 0; i < arraySize; i++) {
            new_Aptr[i + 1] = aptr[i];
        }

        arraySize++;

        delete[] aptr;

        aptr = new_Aptr;

        aptr[0] = val;
    }
    catch(bad_alloc) {
        memError();
    }
}

template <class T>
void SimpleVector<T>::push_back(T val){
    try {
        T *new_Aptr = new T[arraySize + 1];

        for (int i = 0; i < arraySize; i++) {
            new_Aptr[i] = aptr[i];
        }

        delete[] aptr;

        aptr = new_Aptr;

        aptr[arraySize] = val;

        arraySize++;
    }
    catch(bad_alloc) {
        memError();
    }
}

template <class T>
T SimpleVector<T>::pop_front(){
   T dummy;
    try {
        T *new_Aptr = new T[arraySize - 1];

        arraySize--;

        for (int i = 0; i < arraySize; i++) {
            new_Aptr[i] = aptr[i + 1];
        }

        delete[] aptr;

        aptr = new_Aptr;

        return dummy;
    }
    catch(bad_alloc) {
        memError();
    }

}

template <class T>
T SimpleVector<T>::pop_back(){
    T dummy;
    try {
        T *new_Aptr = new T[arraySize - 1];

        arraySize--;

        for (int i = 0; i < arraySize; i++) {
            new_Aptr[i] = aptr[i];
        }

        delete[] aptr;

        aptr = new_Aptr;    

        return dummy; 
    }
    catch(bad_alloc) {
        memError();
    }
}
#endif

А вот основной класс, предоставленный моим инструктором.

main.cpp:
#include "SimpleVector.h"
void fillVec(SimpleVector<int> &);
void addVec(SimpleVector<int> &);
void delVec(SimpleVector<int> &);
void prntVec(SimpleVector<int> &,int);

//Execution Begins Here!
int main(int argc, char** argv) {
    //Declare Variables
    int size;

    //Read in the size
    cout<<"What size vector to test?"<<endl;
    cin>>size;
    SimpleVector<int> sv(size);

    //Initialize or input i.e. set variable values
    fillVec(sv);

    //Display the outputs
    prntVec(sv,10);

    //Add and subtract from the vector
    addVec(sv);

    //Display the outputs
    prntVec(sv,10);

    //Add and subtract from the vector
    delVec(sv);

    //Display the outputs
    prntVec(sv,10);

    //Exit stage right or left!
    return 0;
}

void addVec(SimpleVector<int> &sv){
    int add=sv.size()*0.1;
    for(int i=1;i<=add;i++){
        sv.push_front(i+add-1);
        sv.push_back(i-add);
    }
}

void delVec(SimpleVector<int> &sv){
    int del=sv.size()*0.2;
    for(int i=1;i<=del;i++){
        sv.pop_front();
        sv.pop_back();
    }
}

void fillVec(SimpleVector<int> &sv){
    for(int i=0;i<sv.size();i++){
        sv[i]=i%10;
    }
}
void prntVec(SimpleVector<int> &sv,int n){
    cout<<endl;
    for(int i=0;i<sv.size();i++){
        cout<<sv[i]<<" ";
        if(i%n==(n-1))cout<<endl;
    }
    cout<<endl;
}

У меня есть некоторая свобода действий с main.cpp (так как это немного схематично). Что еще более важно, мне нужно знать, с чего начать с приведенных инструкций. Спасибо !!

1 Ответ

0 голосов
/ 08 апреля 2019

Я не уверен на 100%, что это то, о чем просит ваш профессор, но из того, что я могу собрать, для части 1 вы должны изменить свой векторный класс так, чтобы он выделял память только тогда, когда вы достигли конца вектора или достичь 1/4 объема памяти.

Например, в вашей функции push_front вы выделяете новую память каждый раз, когда добавляете одно значение в вектор. Вместо этого вы должны выделять память только тогда, когда вы достигаете своего объема памяти и удваиваете его вместо добавления 1. Аналогично, при удалении значения из вашего массива вы не удаляете память, пока ваш векторный размер не станет 1/4 от выделенной памяти .

Для второй части вопроса я бы порекомендовал создать второй класс Node, содержащий данные и указатель на другой Node. В вашем векторном классе у вас будет указатель на первый Node в списке. Поскольку это односвязный список, чтобы найти свое значение, вы можете перебирать список определенное количество раз или до тех пор, пока следующий указатель не будет равен NULL.

Судя по вашему вопросу, кажется, что вы просто хотели получить отправную точку для выполнения задания, поэтому, надеюсь, вышеизложенное поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...