подскажите пожалуйста почему не выделяется память в строке CLNAME* tmp=new CLNAME[this->Capacity_Ram];
второй день ищу проблему не могу понять в чем проблема. Задача состоит в том, чтобы написать самописные векторы
Код:
заголовок:
#pragma once
#include <iostream>
#include <memory.h>
using namespace std;
template <class CLNAME>
class MyVector{
protected:
CLNAME* Array;
int Size_Ram = 0;
int Capacity_Ram = 5;
public:
MyVector();
MyVector(const MyVector<CLNAME> &other);
int Capacity();
int Size();
void PushBack(CLNAME item);
};
#include "MyVector.ipp"
ипп:
//Конструкторы
template <class CLNAME>
MyVector<CLNAME>::MyVector() {
this->Array = new CLNAME[this->Capacity_Ram];
}
template <class CLNAME>
MyVector<CLNAME>::MyVector(const MyVector<CLNAME> &other) {
this->Capacity_Ram=other.Capacity_Ram;
this->Size_Ram=other.Size_Ram;
Array = new CLNAME[other.Capacity_Ram];
for (int i=0;i<other.Size_Ram;i++){
this->Array[i]=other.Array[i];
}
}
//Методы
template <class CLNAME>
int MyVector<CLNAME>::Capacity(){
return(this->Capacity_Ram);
};
template <class CLNAME>
int MyVector<CLNAME>::Size(){
return(this->Size_Ram);
};
template <class CLNAME>
void MyVector<CLNAME>::PushBack(CLNAME item) {
if (this->Size_Ram==0){
Array = new CLNAME[this->Capacity_Ram];
this->Capacity_Ram=Capacity_Ram*2;
}
if (Size_Ram==Capacity_Ram){
this->Capacity_Ram=Capacity_Ram*2;
CLNAME* tmp=new CLNAME[this->Capacity_Ram];
for (int i=0;i<Size_Ram;i++){
tmp[i]=Array[i];
}
delete [] Array;
Array = tmp;
}
Array[Size_Ram]=item;
Size_Ram+=1;
}
//template <class CLNAME>
//MyVector<CLNAME> MyVector<CLNAME>::operator=(MyVector<CLNAME> other) {
//if (*this == other){
//return *this
//}
//this->Size_Ram=other.Size;
//this->Capacity_Ram=other.Capacity;
//this->Array=other.Array;
//};
главный:
#include <iostream>
#include "MyVector.h"
int main() {
MyVector<int> vectors;
int a=65;
cout<<vectors.Capacity()<<endl;
cout<<vectors.Size()<<endl;
for (int i=0;i<=10;i++) {
vectors.PushBack(i);
}
cout<<vectors.Size()<<endl;
cout<<vectors.Capacity()<<endl;
}
Проблема с ошибками повреждения памяти заключается в том, что вы видите ошибку после того, как память уже была повреждена. Скорее всего, вы где-то пишете за пределами выделенного блока. Дезинфекция адресов может помочь в этом: godbolt.org/z/bcsT8en67 Взгляните на порядок, в котором вы назначаете емкость и выделяете память, когда размер равен 0 в PushBack
.
Взгляните на if (this->Size_Ram==0)
. Вы выделяете 5 элементов, но затем сохраняете 10 в качестве предполагаемой емкости. Нажатие шестого элемента записывает за конец вашего массива из 5 элементов.
Хотя пункт спорный. Как указывает @Lala5th выше, весь этот if
не нужен.
Не связано: для завершения Правило трехMyVector
требуется оператор присваивания.
Возможно, вы также захотите реализовать семантику перемещения в дополнение к правилу трех.
@ user4581301 и деструктор
Святой <ругательство удалено>. Даже не заметил, что деструктор отсутствует.
В MyVector<CLNAME>::PushBack
if (this->Size_Ram==0){
Array = new CLNAME[this->Capacity_Ram]; // already done in constructor, leaks.
// sets capacity of 5
this->Capacity_Ram=Capacity_Ram*2; // advertises a capacity of 10, not 5.
}
делает 2 ошибки. 1) хранилище уже было выделено в конструкторе, поэтому это приводит к утечке выделения конструктора и не нужно. 2) Array = new CLNAME[this->Capacity_Ram];
запрашивает массив из Capacity_Ram
элементов, а затем сбрасывает емкость, чтобы Capacity_Ram=Capacity_Ram*2;
испортить if (Size_Ram==Capacity_Ram)
тесты емкости позже в программе и разрешить доступ за пределами границ.
Решение: удалить весь первый if
и заблокировать. Конструктор уже сделал это.
Примечание: этому классу нужен оператор присваивания и деструктор, чтобы работать вместе с конструктором копирования.
Примечание:
Array = new CLNAME[this->Capacity_Ram];
вPushBack
, еслиSize_ram == 0
происходит утечка памяти, поскольку этот фрагмент уже выделен в конструкторе и никогда не освобождается. Также массив выходит за пределы области видимости, но никогда не освобождается, поскольку деструктор отсутствует.