Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.02.2019, 14:33   #1
Rodnik2009
Новичок
Джуниор
 
Регистрация: 25.02.2019
Сообщений: 1
По умолчанию Инициализация динамического массива в классе с использованием шаблона

Доброго времени суток. Буду признателен за помощь, ни разу не сталкивался с шаблонными типами. Программа получилась нормальная вроде, но в методе
void UpCapacity(int NewCapacity)

на строке free(a)
а также на строке
free (b) -
выпадает исключение.

Прикладываю листинг полностью.
Код:
#include <iostream>
 
using namespace std;
 
template <typename T>                               //СОЗДАНИЕ ШАБЛОННА
class MyVector {
 
private:
    int length;
    int capacity;
    T* a;
 
public:
    MyVector() {                                 //КОНСТРУКТОР ВЕКТОРА
        length = 0;
        capacity = sizeof(T);
        a = (T*)malloc(sizeof(T));
    }
 
    T& operator[] (int index) {                     //ПЕРЕОПРЕДЕЛЕНИЕ "[]"
        T k = a[index];
        return(k);
    }
 
    void PushBack(int NewElement) {                 //УВЕЛИЧЕНИЕ ФИЗ(ЕСЛИ НУЖНО) И ЛОГ ПАМЯТИ
        IsEmpty();
        a[length] = NewElement;
        ++length;
 
    }
 
 
    void IsEmpty() {                                //проверка на нехватку физ памяти
        if (capacity < length*sizeof(T)) {
            UpCapacity(capacity+sizeof(T));
        }
    }
 
private:
    void UpCapacity(int NewCapacity) {              //РЕЛОКАЦИЯ ПАМЯТИ
 
        T* b = (T*) malloc(capacity);
 
        for (int i = 0; i < capacity; i++) {
            b[i] = a[i];
        }
 
        free(a);
 
        a = (T*)malloc(NewCapacity);
 
        for (int i = 0; i < capacity; i++) {
            a[i] = b[i];
        }
        capacity = NewCapacity;
        free(b);
 
    }
 
public:
    int Length() {
        return(length);
    }
 
    int Capacity() {
        return(capacity);
    }
 
    void Input1(int n) {
        for (int i = 0; i < n; i++) {
            PushBack(1);
        }
    }
 
    void Input(int n) {
        for (int i = 0; i < n; i++) {
            PushBack(i);
        }
    }
 
    void Output() {
        cout << "Массив: " << endl;
        for (int i = 0; i < Length(); i++) {
            cout << a[i] << " ";
        }
        cout << endl;
        cout << "Лог размер массива: " << Length() << endl;
        cout << "Физ размер массива: " << Capacity() << endl;
 
    }
 
 
    const int& At(int index) const {
        return a[index];
    }
 
    MyVector(const MyVector& right) : length(right.length), capacity(right.capacity), a((T*)malloc(right.capacity * sizeof(T))) {
        for (int i = 0; i < length; i++) {
            a[i] = right.a[i];                                          //конструктор КОПИРОВАНИЯ
        }
    }
 
    bool operator !=(const MyVector<T>& Data)
    {
        MyVector<T>* cur_p = this->a;
        MyVector<T>* cur_Dp = Data.a;
        return (cur_p != cur_Dp);
    }
    MyVector<T>& operator= (const MyVector<T>& right) {              //операторо ПРИСВАИВАНИЯ
        if (this != &right) {
            free(a);
            length = right.length;
            capacity = right.capacity;
            a = (T*)malloc(capacity*sizeof(T));
            for (int i = 0; i < length; i++) {
                a[i] = right.a[i];
            }
        }
        return (*this);
    }
 
    void InputSetSize(int N) {                              //ПРИНУДИТЕЛЬНОЕ ИЗМЕНЕНИЕ ЛОГ РАЗМЕРА ВЕКТОРА
        free(a);
        length = N;
        capacity = N*sizeof(T);
        a = (T*)malloc(capacity);
        for (int i = 0; i < N; i++) {
            a[i] = i;
        }
    }
 
    ~MyVector() {
        free(a);
    }
};
 
//______________________________________________________________________________ФУНКЦИИ___________
 
template <class MyType>
void MySwap(MyType& element1, MyType& element2) {                     //ОБМЕН МЕСТАМИ
    MyType element3 = element1;
    element1 = element2;
    element2 = element3;
}
 
//____________________________________________________________________________ТЕЛО ПРОГРАММЫ_______
 
int main() {
    setlocale(LC_ALL, "RUS");
 
    MyVector<float>* vec= new MyVector<float>();
    MyVector<float>* vec1=new MyVector<float>();
    MyVector<float>* vec2= new MyVector<float>();
    int size = 5;
 
    vec->InputSetSize(10);                             //СОЗДАНИЕ ВЕКТОРА С ПОМОЩЬЮ ПРИНУДИТЕЛЬНОГО ИЗМЕНЕНИЯ ЛОГ ПАМЯТИ
    vec1->Input1(size);
 
    MySwap(vec, vec1);
    vec2 = vec;
 
    vec->Output(); //ВЫВОД ПЕРВОГО ВЕКТОРА
    vec1->Output(); //ВЫВОД ВТОРОГО ВЕКТОРА
    vec2->Output(); //ВЫВОД ПЕРВОГО ВЕКТОРА, ПРИСОВЕННОГО ТРЕТЬЕМУ
 
    return 0;
}
Rodnik2009 вне форума Ответить с цитированием
Старый 25.02.2019, 17:50   #2
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Rodnik2009 Посмотреть сообщение
Прикладываю листинг полностью.
умничка.
подача материала - годная.

теперь внимательно смотри:

Код:
    void PushBack(int NewElement) {                 //УВЕЛИЧЕНИЕ ФИЗ(ЕСЛИ НУЖНО) И ЛОГ ПАМЯТИ
        IsEmpty();
        a[length] = NewElement;
        ++length;
 
    }
 
 
    void IsEmpty() {                                //проверка на нехватку физ памяти
        if (capacity < length*sizeof(T)) {
            UpCapacity(capacity+sizeof(T));
        }
    }
когда отрабатывает твой первый PushBack, у тебя length равен нулю, а capacity равно 4.

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

в результате вот здесь:
a[length] = NewElement;
++length;

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

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

поэтому она делает ему живительный укол эвтаназии.
от греха подальше.

замени на:
Код:
void IsEmpty() {                                //проверка на нехватку физ памяти
        if (capacity <= length*sizeof(T) + sizeof(T) ) {
            UpCapacity(capacity+sizeof(T));
        }
    }
_Bers вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Инициализация динамического массива RAFA91 Общие вопросы C/C++ 22 13.08.2015 14:49
Инициализация ДВУМЕРНОГО массива в классе IgoreKMaN Общие вопросы C/C++ 1 01.04.2014 12:39
Операция сложения для многоразрядных числ (больше 100) с использованием динамического массива (делфи) Таня =) Помощь студентам 1 22.04.2012 15:34
Инициализация в классе t2skler Общие вопросы C/C++ 6 19.03.2012 21:54
Использование шаблона stack в классе Jugger Помощь студентам 1 24.11.2011 22:01