Я создаю программу анализа изображений в c++. Он принимает текстовый файл, который содержит значения для построения изображения с серой шкалой. Я использую сумму квадратов различий, чтобы найти конкретный блок на этом изображении. Он построен с использованием класса matrix в заголовочном файле, поэтому у меня есть два перегруженных конструктора и деструктор, который удаляет указатель на double, который выделяет память на куча для этого огромного массива значений (768 x 1024). Однако это порождает ошибку памяти; Ошибка отладки, выражение: тип блока действителен. Я не могу понять, почему это происходит. Для расчета SSD я использую два для циклов; два объекта матрицы обрабатываются, одна из этих поправок вызывает один из конструкторов для создания нового объекта матрицы из получения блока из более крупного объекта матрицы. Я понимаю, что деструктор вызывается дважды через каждый цикл, поскольку объекты выходят из области видимости? Является ли это двойное удаление и почему возникает ошибка? Ниже приведены мои конструкторы и циклы. Если кто-нибудь может понять, почему я получаю эту ошибку, я был бы очень доволен.
Конструкторы:
// Matrix constructor creating a new matrix object where all elements are the same number
Matrix::Matrix(int sizeR, int sizeC, double val)
{
//cout << "Matrix(int sizeR, int sizeC, double val) is invoked.." << endl;
M = sizeR;
N = sizeC;
data = new double[M * N];// Initialise space for class array 'data'
for (int i = 0; i < M* N; i++)
{
data[i] = val;// Set each element of the array to the same value passed to the constructor from main
}
}
// Matrix constructor taking pointer to array as input; creates a new matrix object
Matrix::Matrix(int sizeR, int sizeC, double* input_data)
{
//cout << "Matrix::Matrix(int sizeR, int sizeC, double* input_data) is invoked...." << endl;
M = sizeR;
N = sizeC;
data = new double[M * N];// Initialise space for class array 'data'
for (int i = 0; i < M * N; i++)
{
data[i] = input_data[i];// Set elements in data as elements from input_data passed to the constructor from main
}
}
деструктор:
// Matrix destructor
Matrix::~Matrix()
{
//cout << "Matrix::~Matrix() is invoked..." << endl;
delete data;
}
Код в основном:
for (int i = 0; i < (768 - 21); i++)
{
for (int j = 0; j < (1024 - 21); j++)
{
counter++;
clutteredBlock = cluttered.getBlock(i, (i + 21), j, (j + 21));
diff = clutteredBlock - wallyBlock;
diff = diff * diff;
tempVal = diff.Sum();
if (i == 0 && j == 0)
{
ssd = tempVal;
}
if (tempVal <= ssd)
{
ssd = tempVal;
co1 = i;
co2 = j;
}
}
}
Таким образом, M, N и данные являются членами частного класса; M и N - int
а данные - double*
; данные, являющиеся указателем, который я пытаюсь удалить и получить в никуда.
UPDATE: Если я проигнорирую ошибку, я получаю ошибку HEAP CORRUPTION, говорящую, что я пытаюсь записать в кучу после буфера?
ОБНОВЛЕНИЕ: оператор присваивания;
Matrix& Matrix::operator=(const Matrix& input)
{
//cout << "Matrix::operator= is invoked..." << endl;
if (this == &input)
{
return *this;
}
else
{
delete data;
M = input.getR();
N = input.getC();
data = new double[M * N];
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
Set(i, j, input.Get(i, j));
}
}
}
return *this;
}
Любой вход очень приветствуется :)
Используйте std::vector
для вашего хранилища. Он автоматически обрабатывает выделение и освобождение. Задача решена.
new
, или что-то еще - лучше всего просто заключить в кавычки дословное назначение).
delete[] data;
также подумайте об использовании std :: unique_ptr или std :: shared_ptr (если у вас нет C ++ 11, используйте std :: auto_ptr), они автоматически очистят динамическую память, которой они управляют