没有编译错误的第一次机会异常

时间:2015-01-06 12:48:54

标签: c++ first-chance-exception

我编写的代码编译没有错误,因此我不知道错误发生的原因。

#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; 

(至少这是一些黄色箭头指向的代码行)

程序用于矩阵(+, - ,*)上的操作。我以类似的方式为欧几里得矢量操作编写了一个程序,它完美无缺。

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您的代码中存在许多会导致问题的问题:

  1. 您的构造函数Macierz(int _x, int _y)不能像您认为的那样工作。只有wiersze[0]在完成后才有效,任何非零索引都将访问未知内存。问题在于您的2D矩阵类的设计。我会摆脱手动管理的内存,只使用2D矢量vector<vector<int>>甚至只是平面1D矢量并手动管理索引。
  2. 您的复制构造函数Macierz(Macierz &m)不会为新矩阵分配内存,因此您正在写入未知内存。
  3. 所有二元运算符(+, - ,*)都会分配一个新对象并将其返回,这将导致泄漏的内存。规范的方法通常是修改对象,只为这些操作符return *this;。有关运算符重载的详细信息,请参阅this question
  4. 您的复制操作符Macierz::operator=(Macierz &m)不会检查矩阵是否大小相同。如果它的大小不同,则需要销毁并重新分配矩阵。
  5. 您的Macierz::operator()(int x, int y)不会检查可能有意的输入索引,但您可能会考虑像使用其他方法一样抛出异常。
  6. 你没有析构函数会导致内存泄露,但如果你使用vector<>则不需要。{/ li>

    如果你真的需要/想要从头开始实现2D矩阵类,你可以在线搜索各种现有代码,例如this one,作为做什么的例子。

答案 1 :(得分:0)

由于有许多指针算术,我敢打赌这是一个内存访问问题 无论如何,当你使用C ++时,你应该利用矩阵类而不是重新发明轮子...
例如Basic Linear Algebra Library及其matrix类是最佳参考 使用这样的类,在调试模式下编译时,会检查内存访问并帮助您快速错误索引。