2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Потеря значений. С++
Сообщение01.06.2010, 13:02 
Аватара пользователя


01/06/10
6
Программа должна находить проиведения 2х матриц. Но при выводе видно, что происходит потеря значений или же они просто не доходят до функции вывода... Я подозреваю, что дела в конструкторе копирования

Код:
Код:
#include "stdafx.h"
using namespace std;
class matrix{
int **m;
int n;
public:
matrix()
   {m=0;n=0;}
matrix(int n1) // конструктор
   {int i,j;
   n=n1;
   m=new int* [n];
   for (i=0;i<n;i++)
      m[i]=new int[n];
   for(i=0;i<n;i++)
      for(j=0;j<0;j++)
         m[i][j]=0;}
~matrix() //деструктор
               {for(int i=0;i<n;i++)
               delete [](m[i]);
               delete[]m;}
matrix(const matrix&p) //конструктор копирования
   {int i,j;
   n=p.n;m=0;
   m=new int*[n];
   for (i=0;i<n;i++)
   m[i]=new int[n];
   for(i=0;i<n;i++)
      for(j=0;j<0;j++)
         m[i][j]=p.m[i][j];}
matrix mult(matrix l) //функция перемножения матриц
   {matrix p;
   int i,j,k;
   p.m=new int* [n];
   for (i=0;i<n;i++)
      p.m[i]=new int[n];
   for(i=0;i<n;i++)
      for(j=0;j<0;j++)
         p.m[i][j]=0;
   for (i=0;i<n;i++)
      for(j=0;j<n;j++)
         for(k=0;k<n;k++)
         p.m[i][j]=p.m[i][j]+m[i][k]+l.m[k][j];
   p.n=n;
   return p;}
void input(int n1) //ввод матрицы с клавиатуры
   {int i,j;n=n1;
   for(i=0;i<n;i++)
   for(j=0;j<n;j++)
   {cout<<"["<<i<<","<<j<<"]=";
   cin>>m[i][j];}}
void output() //вывод матрицы
              {for(int i=0;i<n;i++)
              {for(int j=0;j<n;j++)
               cout<<m[i][j]<<" ";
               cout<<endl;}
               }};

int _tmain(int argc, _TCHAR* argv[])
             {matrix m1(2),l1(2),p1(2);
              m1.input(2);l1.input(2);
              p1=m1.mult(l1);
              p1.output();
              getchar();
              getchar();
              return 0;
}


Подскажите, пожалуйста, где происходит потеря?

 Профиль  
                  
 
 Re: Потеря значений. С++
Сообщение01.06.2010, 13:10 


26/01/10
959
Первая ошибка, которую удалось найти за минуту случайного поиска:
Код:
for(j=0;j<0;j++)

Это в функции перемножения матриц. Что бы это значило? Если ошибка в этой строке, то все ясно, а если нет, будем думать дальше...

Далее, если бы я преподавал у Вас, то сделал бы замечание: здесь нет смысла передавать в функцию перемножения матриц всю матрицу целиком, можно передавать только ссылку на неё. А внутри функции перемножения матриц вместо того, чтобы выделять память для p, можно было бы вызвать Ваш конструктор, который как раз это и делает.

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

 Профиль  
                  
 
 Re: Потеря значений. С++
Сообщение01.06.2010, 13:17 
Аватара пользователя


01/06/10
6
Zealint в сообщении #326255 писал(а):
Первая ошибка, которую удалось найти за минуту случайного поиска:
Код:
for(j=0;j<0;j++)

Это в функции перемножения матриц. Что бы это значило? Если ошибка в этой строке, то все ясно, а если нет, будем думать дальше...


Я невнимательна... Исправила. Не заработало. Выдает (и выдавал) ошибку в строке
Цитата:
cout<<m[i][j]<<" ";
функции output()

Цитата:
Далее, если бы я преподавал у Вас, то сделал бы замечание: здесь нет смысла передавать в функцию перемножения матриц всю матрицу целиком, можно передавать только ссылку на неё. А внутри функции перемножения матриц вместо того, чтобы выделять память для p, можно было бы вызвать Ваш конструктор, который как раз это и делает.
Спасибо, действительно ценные замечания. Но пока я бы просто хотела, чтобы она заработала.
Цитата:
Кстати, деструктор неправильно написан. Он будет удалять память даже тогда, когда она не выделена, что приведет к аварийному завершению программы.

Я зануляю значения в любом случае. (В первом конструкторе). А насколько я знаю, delete может быть применен к обьектам, сделанным new или же к 0.

 Профиль  
                  
 
 Re: Потеря значений. С++
Сообщение01.06.2010, 13:28 


26/01/10
959
Olga1706 в сообщении #326257 писал(а):
А насколько я знаю, delete может быть применен к обьектам, сделанным new или же к 0.


Очень сомневаюсь. По крайней мере, не все компиляторы это умеют. Ну ладно.

Ошибка мне теперь очевидна. Помимо того, что Вы забыли знак "умножить" написать где нужно, Вы не написали оператор присваивания, который компилятор написал за Вас сам и сделал это (конечно же) не правильно (он же не знает, что у Вас динамическая память). А вы этим оператором пользуетесь один раз. Там и потеря, поскольку Вы обращаетесь (после присваивания p1=...) к несуществующей памяти.

 Профиль  
                  
 
 Re: Потеря значений. С++
Сообщение01.06.2010, 13:39 
Аватара пользователя


01/06/10
6
Zealint в сообщении #326261 писал(а):
Olga1706 в сообщении #326257 писал(а):
А насколько я знаю, delete может быть применен к обьектам, сделанным new или же к 0.


Очень сомневаюсь. По крайней мере, не все компиляторы это умеют. Ну ладно.

Это нам препод как заклинание твердит. (по умолчанию он всегда говорит про Visual Studio)

Цитата:
Помимо того, что Вы забыли знак "умножить" написать где нужно,

Действительно. Даже стыдно за свою невнимательность.

Цитата:
Вы не написали оператор присваивания, который компилятор написал за Вас сам и сделал это (конечно же) не правильно (он же не знает, что у Вас динамическая память). А вы этим оператором пользуетесь один раз. Там и потеря, поскольку Вы обращаетесь (после присваивания p1=...) к несуществующей памяти.

Тогда у меня вопрос: а можно ли без него обойтись? (просто мы его не проходили)

 Профиль  
                  
 
 Re: Потеря значений. С++
Сообщение01.06.2010, 13:44 
Заслуженный участник


04/05/09
4587
Zealint в сообщении #326261 писал(а):
Очень сомневаюсь. По крайней мере, не все компиляторы это умеют. Ну ладно.
Лет 20 назад, до появления стандарта C++, это умели не все компиляторы (но почти все). Сейчас же в этом можно не сомневаться.

(Оффтоп)

На embedded системы пока лучше не обращать внимания - там может быть настолько урезанная версия C++, что и исключенииями тоже нельзя будет пользоваться.


-- Вт июн 01, 2010 06:50:12 --

Olga1706 в сообщении #326267 писал(а):
Тогда у меня вопрос: а можно ли без него обойтись? (просто мы его не проходили)
Можно, но неудобно.
Сделайте функцию умножения с тремя параметрами, и без возвращаемого результата.
Матрицу результата передавайте первым параметром по ссылке.

 Профиль  
                  
 
 Re: Потеря значений. С++
Сообщение01.06.2010, 13:58 
Аватара пользователя


01/06/10
6
venco в сообщении #326270 писал(а):
Сделайте функцию умножения с тремя параметрами, и без возвращаемого результата.

А почему с тремя?

Я попробовала сделать
Код:
void mult(matrix l,matrix p)
   {int i,j,k;
   for(i=0;i<n;i++)
   for(j=0;j<n;j++)
    m[i][j]=0;
   for (i=0;i<n;i++)
      for(j=0;j<n;j++)
         for(k=0;k<n;k++)
         m[i][j]=m[i][j]+p.m[i][k]*l.m[k][j];
   }

И программа запустилась, но выводит она запредельно большие значения - т.е. она опять теряет.

 Профиль  
                  
 
 Re: Потеря значений. С++
Сообщение01.06.2010, 14:08 


26/01/10
959
venco в сообщении #326270 писал(а):
Лет 20 назад, до появления стандарта C++, это умели не все компиляторы (но почти все). Сейчас же в этом можно не сомневаться.

Хорошо, не буду. Это действительно старая школа, старые привычки.

Olga1706 в сообщении #326279 писал(а):
А почему с тремя?

Первый - результат, остальные два - первая и вторая матрицы соответственно.

Olga1706 в сообщении #326279 писал(а):
И программа запустилась, но выводит она запредельно большие значения - т.е. она опять теряет.

А у меня с этой функцией все работает... Чтобы понять ошибку, Вам придётся заново скопировать свой код сюда. Где-то в другом месте косяк.

 Профиль  
                  
 
 Re: Потеря значений. С++
Сообщение01.06.2010, 14:14 
Аватара пользователя


01/06/10
6
Zealint в сообщении #326284 писал(а):
придётся заново скопировать свой код сюда

Пожалуйста:
Код:
#include "stdafx.h"
using namespace std;
class matrix{
               int **m;
   int n;
public:
   matrix()
      {m=0;n=0;}
   matrix(int n1)
      {int i,j;
      n=n1;
      m=new int* [n];
      for (i=0;i<n;i++)
         m[i]=new int[n];
      for(i=0;i<n;i++)
         for(j=0;j<0;j++)
            m[i][j]=0;}
   ~matrix()
      {for(int i=0;i<n;i++)
      delete [](m[i]);
      delete[]m;}
   matrix(matrix const&p)
      {int i,j;
      n=p.n;m=0;
      m=new int*[n];
      for (i=0;i<n;i++)
         m[i]=new int[n];
      for(i=0;i<n;i++)
         for(j=0;j<0;j++)
            m[i][j]=p.m[i][j];}
   void mult(matrix l,matrix p)
      {int i,j,k;
      for(i=0;i<n;i++)
      for(j=0;j<n;j++)
       m[i][j]=0;
      for (i=0;i<n;i++)
         for(j=0;j<n;j++)
            for(k=0;k<n;k++)
            m[i][j]=m[i][j]+p.m[i][k]*l.m[k][j];
         }
   void input(int n1)
      {int i,j;n=n1;
      for(i=0;i<n;i++)
      for(j=0;j<n;j++)
      {cout<<"["<<i<<","<<j<<"]=";
      cin>>m[i][j];}}
   void output()
   {for(int i=0;i<n;i++)
   {for(int j=0;j<n;j++)
   cout<<m[i][j]<<" ";
   cout<<endl;}
   }};

int _tmain(int argc, _TCHAR* argv[])

{matrix m1(2),l1(2),p1(2);
m1.input(2);l1.input(2);
p1.mult(l1,m1);
p1.output();
getchar();
getchar();

   return 0;
}


Тут функция mult с двумя аргументами. Как я поняла с 3мя - это уже не как функцию-член класса писать надо.

 Профиль  
                  
 
 Re: Потеря значений. С++
Сообщение01.06.2010, 14:26 


26/01/10
959
Olga1706 в сообщении #326290 писал(а):
Пожалуйста


Госпожа Olga1706, зачем опять написали в НЕСКОЛЬКИХ местах

Код:
for(j=0;j<0;j++)
?

в умножении и в конструкторе. Когда учитесь программировать, надо запретить себе копирование кода вообще. Даже когда 10 раз по 10 одинаковых строк пишите. Линейкой по рукам надо чтобы били : )

Во-вторых, в Вашу замечательную функцию mult лучше передавать аргументы по ссылке. А иначе лишний раз (даже два) конструктор копирования гоняете. Хотя это не ошибка.

Olga1706 в сообщении #326290 писал(а):
Тут функция mult с двумя аргументами. Как я поняла с 3мя - это уже не как функцию-член класса писать надо.

Да.

-- Вт июн 01, 2010 14:32:17 --

А зачем Вы в Visual Studio пишите и используете getchar() в конце?
Там же была возможность нажимать ctrl+F5, чтобы оставлять консоль открытой после исполнения кода. Я-то сам в FAR пишу, поэтому консоль всегда видно.

 Профиль  
                  
 
 Re: Потеря значений. С++
Сообщение01.06.2010, 14:37 
Аватара пользователя


01/06/10
6
Zealint в сообщении #326294 писал(а):
в умножении и в конструкторе. Когда учитесь программировать, надо запретить себе копирование кода вообще. Даже когда 10 раз по 10 одинаковых строк пишите. Линейкой по рукам надо чтобы били : )
Какая я балда!
Всё заработало.
Давно я не чувствовала себя таким идиотом. (К слову сказать, я код стараюсь не копировать. Но то ли тут не удержалась, то ли так вот и написала 2 раза)
Zealint в сообщении #326294 писал(а):
Во-вторых, в Вашу замечательную функцию mult лучше передавать аргументы по ссылке. А иначе лишний раз (даже два) конструктор копирования гоняете. Хотя это не ошибка.
Переделала)

Спасибо огромное за помощь и советы!

-- Вт июн 01, 2010 15:38:44 --

Zealint в сообщении #326294 писал(а):
А зачем Вы в Visual Studio пишите и используете getchar() в конце?Там же была возможность нажимать ctrl+F5, чтобы оставлять консоль открытой после исполнения кода. Я-то сам в FAR пишу, поэтому консоль всегда видно.
А вот об этом нам не рассказали... Партизаны...
Мне самой этот способ не нравился. Спасибо за подсказку, буду пользовать.

 Профиль  
                  
 
 Re: Потеря значений. С++
Сообщение13.06.2010, 10:51 


13/06/10
3
Zealint в сообщении #326261 писал(а):
Olga1706 в сообщении #326257 писал(а):
А насколько я знаю, delete может быть применен к обьектам, сделанным new или же к 0.


Очень сомневаюсь. По крайней мере, не все компиляторы это умеют. Ну ладно.



в стандарте С++ явно прописана возможность delete нулевого указателя.

 Профиль  
                  
 
 Re: Потеря значений. С++
Сообщение13.06.2010, 18:32 


26/01/10
959
Vitas в сообщении #330675 писал(а):
в стандарте С++ явно прописана возможность delete нулевого указателя.

Это не мешает существовать ошибкам особенностям в компиляторах. Просто однажды я напоролся. Это было очень давно... Видимо, тогда ещё не было такого стандарта.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 13 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group