помогите разобраться с проблемой, она довольно распространенная и на форуме куча сообщений про это но в моей программе я никак не могу найти где я ошибся, нужен ваш взгляд со стороны. Вот код:
#pragma once
#include <cstring>
class vec
{
public:
vec()
{
m_size = offset;
m_len = 0;
m_vector = new int[m_size];
memset(m_vector, 0, sizeof(m_vector));
}
vec(size_t size)
{
m_size = size;
m_len = 0;
m_vector = new int[m_size];
memset(m_vector, 0, sizeof(m_vector));
}
vec(const vec& orig)
:
m_size(orig.m_size),
m_len(orig.m_len),
m_vector(nullptr)
{
m_vector = new int[m_size];
for (size_t i = 0; i < m_len; ++i)
{
m_vector[i] = orig.m_vector[i];
}
}
~vec()
{
if (m_vector != nullptr)
{
delete[] m_vector;
m_vector = nullptr;
}
}
size_t GetSize()
{
return m_size;
}
size_t GetLength()
{
return m_len;
}
int* GetValue()
{
return m_vector;
}
vec& operator= (const vec& rhs)
{
if (m_vector)
{
delete[] m_vector;
m_vector = nullptr;
m_len = rhs.m_len;
m_vector = new int[m_size];
for (size_t i = 0; i < m_len; ++i)
{
m_vector[i] = rhs.m_vector[i];
}
}
return *this;
}
int& operator[] (size_t index)
{
return m_vector[index];
}
bool operator== (const vec& rhs)
{
if (m_len != rhs.m_len)
return false;
for (unsigned int i = 0; i < m_len; ++i)
{
if (m_vector[i] != rhs.m_vector[i])
return false;
}
return true;
}
bool operator!= (const vec& rhs)
{
if (!(this == &rhs))
return true;
return false;
}
void push_back(int value)
{
if (m_len == m_size)
{
vec v = vec(m_size * (m_size / 2));
v = *this;
this->m_size = v.m_size;
*this = v;
}
m_vector[m_len] = value;
m_len++;
}
void erase(unsigned int pos)
{
m_vector[pos] = m_vector[m_len - 1];
--m_len;
}
void erase(unsigned int begin, unsigned int end)
{
for (unsigned int i = begin; i <= end; ++i)
{
m_vector[i] = m_vector[m_len - i - 1];
}
m_len -= end - begin;
}
void pop_back()
{
m_vector[m_len - 1] = 0;
--m_len;
}
private:
static constexpr size_t offset = 8;
size_t m_size;
size_t m_len;
int* m_vector;
};
#include "Vec.h"
int main()
{
vec v0;
v0.push_back(2);
v0.push_back(22);
v0.push_back(234);
v0.push_back(2325);
printf("\n");
for (unsigned int i = 0; i < v0.GetLength(); ++i)
{
printf("%d ", v0[i]);
}
vec v1(v0);
v1.push_back(532);
v1.push_back(2324);
v1.push_back(1321);
v1.push_back(6532);
v1.push_back(42);
printf("\n");
for (unsigned int i = 0; i < v1.GetLength(); ++i)
{
printf("%d ", v1[i]);
}
vec v2;
v2 = v1;
v2.push_back(456);
v2.push_back(452);
v2.push_back(224);
v2.push_back(12);
v2.push_back(698);
v2.erase(4, 7);
v2.pop_back();
printf("\n");
for (unsigned int i = 0; i < v2.GetLength(); ++i)
{
printf("%d ", v2[i]);
}
std::cin.get();
return 0;
}
Оператор присваивания
vec& operator= (const vec& rhs)
{
// 1. нет проверки на присваивание самому себе
if (m_vector)
// 2. что это за проверка??
// т.е. если текущий вектор пустой - то присваивать не будем?
{
// если беспокоетесь за удаление нулевого указателя -
// не бойтесь delete не сломается (ему можно передавать нулевые указатели)
delete[] m_vector;
m_vector = nullptr; // это лишнее
m_len = rhs.m_len;
m_vector = new int[m_size]; // интересный момент
// выделение новой памяти под такой же размер что и был ранее?
for (size_t i = 0; i < m_len; ++i)
// т.е. если размер текущего массива был меньше чем количество элементов
// массива-аргумента тут будет выход за границы
{
m_vector[i] = rhs.m_vector[i];
}
}
return *this;
}
Учитывая все замечания можно написать следующий оператор присваивания:
vec& operator= (const vec& rhs)
{
if (&rhs == this) return *this; // проверка на присваивание себе
int new_size = rhs.m_size; // новый размер этого (this) массива
int new_len = rhs.m_len; // новая длина массива
int* new_vector = new int[new_size]; // новый массив
for (size_t i = 0; i < new_len; ++i) // копируем все данный в новый массив
new_vector[i] = rhs.m_vector[i];
// теперь уверенно удаляем старый массив
delete[] m_vector;
m_vector = new_vector; // запоминаем новый вектор
// и запонимаем новые размеры
m_size = new_size;
m_len = new_len;
return *this;
}
Функция вставки элемента в конец массива
void push_back(int value)
{
if (m_len == m_size)
{
// новый размер вычисляется странным образом
// т.е. если массив имеет размер 10000
// ему вычислится следующий размер 5000 * 10000 = 50000000
// многовато
// популярные реализации векторов используют старый размер * 1,5 или на 2
vec v = vec(m_size * (m_size / 2));
// тут вобще магический подход
v = *this;
this->m_size = v.m_size;
*this = v;
}
m_vector[m_len] = value;
m_len++;
}
Работающий push_back
будет выглядеть примерно следующим образом:
void push_back(int value)
{
if (m_len == m_size)
{
int new_size = m_size * 1.5; // вычисляем новый размер
int* new_vector = new int[new_size]; // выделяем память под новый массив
for (int i = 0; i < m_len; ++i) // копируем данные из текущего массива в новый
{
new_vector[i] = m_vector[i];
}
delete[] m_vector; // теперь удаляем старый массив
m_vector = new_vector; // запоминаем наш новый массив
m_size = new_size; // запоминаем новый размер
}
m_vector[m_len] = value;
m_len++;
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
ОС - Windows Кодировка входной строки - неизвестна, но скорее всего виндовская будетКодировка файлов проекта - набор символов юникода
При нажатии на кнопку Register должен добавляться новый пользователь в БДКонсоль выдает :
Сегодня запустил свой проект, обновил Intellij IDEA и произошло нечто такое, из-за чего я не могу писать свой прекрасный код