Исключение первого шанса без ошибок компиляции

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

#pragma once
class Macierz
{
public:
class Wiersz
{
public:
int *tab;
int dlugosc;
Wiersz(int d);
};

int x;
int y;
Wiersz *wiersze;
public:
Macierz(int m, int n);
Macierz(Macierz &m);

Macierz & operator+(Macierz &m);
Macierz & operator-(Macierz &m);
Macierz & operator*(Macierz &m);
Macierz & operator=(Macierz &m);
int& operator()(int x, int y);
string to_String();

};

#include "stdafx.h"#include "Macierz.h"

Macierz::Macierz(int _x, int _y) :x(_x), y(_y)
{
Wiersz **tab = new Wiersz*[_x];
for (int i = 0; i < x; i++)
tab[i] = new Wiersz(_y);
wiersze = *tab;
}Macierz::Macierz(Macierz &m) :Macierz(m.x, m.y)
{
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
wiersze[i].tab[j] = m.wiersze[i].tab[j];
}Macierz & Macierz::operator+(Macierz &m)
{
if (x != m.x || y != m.y) throw "Macierze maja rozne rozmiary";
Macierz *temp = new Macierz(m);

for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
(*temp).wiersze[i].tab[j] += wiersze[i].tab[j];

return *temp;
}Macierz & Macierz::operator-(Macierz &m)
{
if (x != m.x || y != m.y) throw "Macierze maja rozne rozmiary";
Macierz *temp = new Macierz(m);

for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
(*temp).wiersze[i].tab[j] -= wiersze[i].tab[j];

return *temp;
}Macierz & Macierz::operator*(Macierz &m)
{
Macierz *temp;
if (x == m.y)
{
temp = new Macierz(m.x, y);
for (int i = 0; i < (*temp).x; i++)
for (int j = 0; j < (*temp).y; j++)
for (int l = 0; l < m.y; l++)
(*temp).wiersze[i].tab[j] += wiersze[i].tab[l] * m.wiersze[l].tab[j];

}
else if (y == m.x)
{
temp = new Macierz(x, m.y);
for (int i = 0; i < (*temp).x; i++)
for (int j = 0; j < (*temp).y; j++)
for (int l = 0; l < y; l++)
(*temp).wiersze[i].tab[j] += wiersze[i].tab[l] * m.wiersze[l].tab[j];
}
else throw "Rozmiary macierzy sie nie zgadzaja";

return *temp;
}Macierz & Macierz::operator=(Macierz &m)
{
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
wiersze[i].tab[j] = m.wiersze[i].tab[j];

return *this;
}int& Macierz::operator()(int x, int y)
{
return wiersze[x].tab[y];
}Macierz::Wiersz::Wiersz(int i)
{
dlugosc = i;
tab = new int[dlugosc];
}string Macierz::to_String()
{

std::ostringstream str;
str << "|";
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
str << wiersze[j].tab[i] << ",";
str << "\b|\n";
}

return str.str();
}

Использование конструктора в main не приводит к сбою программы:

Macierz m1(1,1);

Однако, похоже, существует проблема с доступом к определенному полю данных, например,

 m1(0,0) = 1;

(по крайней мере, это строка кода, на которую указывает желтая стрелка)

Программа используется для операций с матрицами (+, -, *). Я написал аналогичную программу для евклидовых векторных операций, которая прекрасно работает.

Спасибо за помощь заранее.

-6

Решение

В вашем коде много проблем, которые приведут к проблемам:

  1. Ваш конструктор Macierz(int _x, int _y) не работает так, как ты думаешь. Только wiersze[0] будет действительным после его завершения, и любой ненулевой индекс будет обращаться к неизвестной памяти. Проблема действительно в вашем дизайне класса 2D матриц. Я бы избавился от памяти, управляемой вручную, и просто использовал бы 2D вектор vector<vector<int>> или даже просто плоский 1D вектор и управлять индексом вручную.
  2. Ваш конструктор копий Macierz(Macierz &m) не выделяет память для новой матрицы и, следовательно, вы пишете в неизвестную память.
  3. Все ваши двоичные операторы (+, -, *) выделяют новый объект и возвращают его, что приведет к утечке памяти. Каноническим способом обычно является изменение объекта и просто return *this; для таких операторов. Увидеть этот вопрос для более подробной информации о перегрузке оператора.
  4. Ваш оператор копирования Macierz::operator=(Macierz &m) не проверяет, имеет ли матрица одинаковый размер или нет. Если это не тот же размер, вам нужно уничтожить и перераспределить матрицу.
  5. Ваш Macierz::operator()(int x, int y) не проверяет входные индексы, которые могут быть преднамеренно, но вы можете рассмотреть возможность создания исключения, как в других ваших методах.
  6. У вас нет деструктора, который приведет к утечке памяти, хотя, если вы используете vector<> вам не понадобится один.

Если вы действительно хотите / хотите реализовать класс 2D-матрицы с нуля, вы можете искать в Интернете широкий спектр существующего кода, например этот, в качестве примеров того, что делать.

1

Другие решения

Поскольку существует много арифметических указателей, могу поспорить, что это проблема доступа к памяти.
В любом случае, поскольку вы используете C ++, вы должны использовать матричный класс вместо того, чтобы заново изобретать колесо …
Например Библиотека базовой линейной алгебры с его матрица класс является главной ссылкой.
С таким классом, когда он скомпилирован в режиме отладки, доступ к памяти проверяется и помогает быстро ошибиться в индексировании.

0

По вопросам рекламы [email protected]