КИТА unofficial
Май 07, 2024, 09:23:09 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
Новости:
 
   Начало   ПРАВИЛА Помощь WIKI PDA Войти Регистрация  


Страниц: 1 2 [3] 4 5 ... 12   Вниз
  Печать  
Автор Тема: Вопросы в С/С++  (Прочитано 149687 раз)
0 Пользователей и 1 Гость смотрят эту тему.
EvilMax
Администратор
Завкаф
*****

Карма: +59/-0
Offline Offline

Пол: Мужской
Сообщений: 1072


Злой и страшный :)


« Ответ #40 : Март 06, 2008, 12:44:55 »

artem90, описание массива векторов в матрице не годится. Надо vektor **X. С соответствующей модификацией конструктора матрицы с параметрами. Там внутри кое-что придется добавить Подмигивающий Деструктор матрицы, соответственно, тоже усложнится.
Записан

Оптимальная концентрация кофе - это когда код уже дает советы, как его написать, но еще не спорит с тобой и не подкалывает в случае неудач...
---
Существует три способа распространения программного обеспечения: воровство, грабёж и обмен краденым. (c) Неизвестный программист
vimmax
Mодератор
Декан
*****

Карма: +42/-3
Offline Offline

Пол: Мужской
Награды:
лучшая гитара мира
Сообщений: 1713


♪♪ ♫ ♪♪ ♫ ♪♪ ♫ ♪♪


« Ответ #41 : Март 06, 2008, 05:57:23 »

artem90 Значит так:
Ошибки:
1.
Код:
cout<<endl<<"Destroyed MATRIX !!!";
пиши так:
Код:
cout<<"Destroyed MATRIX !!!"<<endl;
Потому, что в текст помещается в буффер, но не выводится сразу на консоль. Чтобы вытолкнуть текст из буффера в поток надо или endl или команда flush(). Удобнее ставить endl в конце. Получается при дебаге текст должен печататься на экране, но реально его нету - он лежит в буфере ))
2.
Делай конструктор по-умолчанию, без параметров. Он все равно нужен. И добавь метод Init() для дополнительной инициализации. Типа:
Код: (cpp)
class vektor
 {
   private:
     int sizeX;
     float *X;
 
   public:
    vektor(int size);
    vektor() { X=NULL; sizeX=0; cout<<"VEKTOR def"<<endl; };
    ~vektor();
    void printVektor()const;
void Init(int size);
};
 
vektor::vektor(int size): sizeX(size) {
   X=new float[sizeX];
   cout<<"Created VEKTOR !!!"<<endl;
}
 
vektor::~vektor()  {
   if(X != NULL) delete[] X;
   cout<<"Destroyed VEKTOR !!!"<<endl;
}

void vektor::Init(int size) {
sizeX = size;
if(X != NULL) delete[] X;
X=new float[sizeX];
}
« Последнее редактирование: Март 06, 2008, 06:08:44 от vimmax » Записан

♪♪ ♫  LET FOREVER BE  ♫ ♪♪ ♫ ♪♪ ♪♪ ♫
Артем
sprata
Mодератор
Завкаф
*****

Карма: +40/-5
Offline Offline

Пол: Мужской
Сообщений: 1107


« Ответ #42 : Март 06, 2008, 06:06:33 »

EvilMax, описание массива векторов в матрице не годится. Надо vektor **X. С соответствующей модификацией конструктора матрицы с параметрами. Там внутри кое-что придется добавить  Деструктор матрицы, соответственно, тоже усложнится.

EvilMaxОписание массива векторов в матрице я исправил, но я не совсем понял почему неподходит *X[] - это ведь массив укзаателей, как раз то что мне и нужно (вроде бы  Строит глазки). Деструктор матрицы тоже исправил. А вот с конструктором матрицы никак не соображу, что там надо поменять, вроде и так все работает  Улыбка

Код: (cpp)
class matrix
  {                               
    private:
      int m,n;
      vektor **X;

    public:
      matrix(int sizeM,int sizeN);
     ~matrix();
      void printMatrix()const;
  };

matrix::matrix(int sizeM,int sizeN): m(sizeM),n(sizeN)
  {
    int i;
    for(i=0; i<m; i++)
      {
        *(X+i)=new vektor(n);
      }
    cout<<endl<<"Created MATRIX";
  }

matrix::~matrix()
  {
    int i;
    for(i=0; i<m; i++)
      {
delete *(X+i);
      }
    cout<<endl<<"Destroyed MATRIX";
    getch();
  }

Записан
vimmax
Mодератор
Декан
*****

Карма: +42/-3
Offline Offline

Пол: Мужской
Награды:
лучшая гитара мира
Сообщений: 1713


♪♪ ♫ ♪♪ ♫ ♪♪ ♫ ♪♪


« Ответ #43 : Март 06, 2008, 06:18:55 »

3. Указатели сразу инициализируй в NULL (X=NULL) и после delete  обратно присваивай в NULL. Пригодится.

4. Если у тебя есть указатель на массив указателей, то для него все равно надо выделить память на массив указателей (стр. 16), а потом по каждому элементу массива снова выделить память для вектора (стр. 20).
Удаление наоборот: удаляешь элементы - вектора X[ i ], а потом удаляешь память по Х (стр 35 и 39).
Код: (cpp)
class matrix
 {                             
   private:
     int m, n;
     vektor **X;
   public:
     matrix(int sizeM,int sizeN);
    ~matrix();
     void printMatrix()const;
 };

matrix::matrix(int sizeM,int sizeN): m(sizeM),n(sizeN)
 {
int i, j;

X = new vektor* [m];

for(i=0;i<m;i++)
{
       X[i]=new vektor[n] ;
   for(j=0;j<n;j++)
   {
   X[i][j].Init(3);
   }
}

   cout<<"Created MATRIX !!!"<<endl;
 }
 
matrix::~matrix()
 {
int i;
for(i=0;i<m;i++)
{
delete[] X[i];
X[i] = NULL;
}

delete [] X;
X = NULL;

cout<<"Destroyed MATRIX !!!"<<endl;
 }


(Отправлено в: 06 Марта 2008, 17:15:53)

Фух.

Работающий вариант тут:
Записан

♪♪ ♫  LET FOREVER BE  ♫ ♪♪ ♫ ♪♪ ♪♪ ♫
EvilMax
Администратор
Завкаф
*****

Карма: +59/-0
Offline Offline

Пол: Мужской
Сообщений: 1072


Злой и страшный :)


« Ответ #44 : Март 07, 2008, 10:15:27 »

vimmax, да, увы, у тебя ошибка. Кубик получился Подмигивающий  Вариант, который сбросил в личку artem90, твоей ошибки не содержит - так что в этот раз обошлось, парень подошел к совету критически.

Polyakov прав в том, что к советам надо относиться осторожно. Советующим - 7 раз отмерь, один отрежь. Тем, кому адресованы советы - относиться к ним критически и проверять. Все мы люди-человеки, а людям свойственно ошибаться.

хз... но в наше время мы рылись по книгам, по инету, по библиотекам, по знакомым... но не получали готовые ответы из инета (форума)....... и что за программисты получатся поле такого развитияНепонимающий
Да, это нехорошо, и вопрос этот поднимался. По-моему, модератор уже как-то отправлял студента из этой тем с вопросом "а что у меня тут не работает?" и совершенно правильно поступал. Поэтому я и не выкладываю полного кода, а ограничиваюсь только общими рекомендациями и консультациями, позволяющими выйти на правильный вариант решения. Был задан вопрос "как это - векторы в матрице?", был дан ответ.

Поэтому просьба к форумчанам: не выкладывайте готовые куски кода лабораторных работ. Например, vimmax мог ограничиться фрагментом кода вроде такого:

Код: (cpp)
class matrix
{
  vector ** rows;
// some other logic
};

matrix::matrix(int m, int n){
  // Create  row array here
  rows = new vector* [m];
  for (int i=0; i<m; i++) {
    // Create each row sized 'n'
    rows[i] = new vector(n);
   // something else
  }
  // some other logic
}


Насчет общей структуры класса, организации деструктора, и к тому же организации вектора и т.п. пусть студент думает сам. А то придет время ему самостоятельно созать класс, а он не сможет даже определить его открытый интерфейс, набор полей и операций...

ЗЫ: просьба относиться к моему посту не как к порицанию или там попытке всех построить - для этого есть модератор раздела, относитесь к нему просто как к дружескому пожеланию. Это, несомненно, даст пользу тем, кто консультируется.
Записан

Оптимальная концентрация кофе - это когда код уже дает советы, как его написать, но еще не спорит с тобой и не подкалывает в случае неудач...
---
Существует три способа распространения программного обеспечения: воровство, грабёж и обмен краденым. (c) Неизвестный программист
TARAKAN
Tifon
Бакалавр
**

Карма: +0/-0
Offline Offline

Пол: Мужской
Сообщений: 134


WWW
« Ответ #45 : Март 11, 2008, 05:32:26 »

Извиняюсь за непонятный символы в коде, не пойму откуда берутся, при редактировании сообщения все время появляются ... думаю понятно и так ...
Код: (cpp)
class matrix
{
  vector ** rows;
// some other logic
};
 
matrix::matrix(int m, int n){
  // Create  row array here
  rows = new vector* [m];
  for (int i=0; i<m; i++) {
    // Create each row sized 'n'
    rows[i] = new vector(n);
   // something else
  }
  // some other logic
}
Соответственно для освобождения памяти надо сделать вот такую вещ ?
Или я чтото путаю ?   mega_shok
Код: (cpp)
matrix::~matrix(int m)
{
  for (int i=0; i<m; i++)
  {
     delete rows[i];
  }
  delete []rows;
}


А при таком создании матрицы (как я понял это оно и делает), потом как обращаться к элементам ? просто rows[ i ][ j ] ? или через указатели ?
« Последнее редактирование: Март 15, 2008, 12:11:36 от Романыч » Записан

Студент: По моему легче использовать printf...
EvilMax: Зато cout - это тру! = ))
TARAKAN
Tifon
Бакалавр
**

Карма: +0/-0
Offline Offline

Пол: Мужской
Сообщений: 134


WWW
« Ответ #46 : Март 11, 2008, 06:05:37 »

Вопрос в том правильно ли вобще я сделал освобождение памяти ? = ))


Получается обращение будет вот таким (после заполнения)
*(*rows+i*n+j)=123;


Или както подругому ?


Немного запутался ...
rows = new vector* [m];
Мы этим действием задаем кол-во строк или столбцов ? В общем параметр "m" в данном выделении памяти означает строки или столбцы ?
« Последнее редактирование: Март 15, 2008, 12:12:03 от Романыч » Записан

Студент: По моему легче использовать printf...
EvilMax: Зато cout - это тру! = ))
vimmax
Mодератор
Декан
*****

Карма: +42/-3
Offline Offline

Пол: Мужской
Награды:
лучшая гитара мира
Сообщений: 1713


♪♪ ♫ ♪♪ ♫ ♪♪ ♫ ♪♪


« Ответ #47 : Март 11, 2008, 06:21:43 »

TARAKAN  по поводу освобождения памяти - подебажься. Заполни матрицу полностью уникальными значениями (типа 0, 1, ... , n) и проверь, чтоб все значения записались правильно. Если эксцепшенов не случилось - значит нормально. (а с виду правильно)))


Цитировать
Получается обращение будет вот таким (после заполнения)
*(*rows+i*n+j)=123;
Или както подругому ?
Чтобы обращение к элемантам матрицы было человеческим - надо перегрузить operator[] или operator(). И всю работу с указателями организовать внутри.
Записан

♪♪ ♫  LET FOREVER BE  ♫ ♪♪ ♫ ♪♪ ♪♪ ♫
TARAKAN
Tifon
Бакалавр
**

Карма: +0/-0
Offline Offline

Пол: Мужской
Сообщений: 134


WWW
« Ответ #48 : Март 11, 2008, 06:32:41 »

vimmax
Цитировать
Чтобы обращение к элемантам матрицы было человеческим - надо перегрузить operator[] или operator(). И всю работу с указателями организовать внутри.
Немного не понял ... как понять перегрузить ... просто я не пойму вобще разницы между [] и () ...
А внутри чего именно ?
Записан

Студент: По моему легче использовать printf...
EvilMax: Зато cout - это тру! = ))
vimmax
Mодератор
Декан
*****

Карма: +42/-3
Offline Offline

Пол: Мужской
Награды:
лучшая гитара мира
Сообщений: 1713


♪♪ ♫ ♪♪ ♫ ♪♪ ♫ ♪♪


« Ответ #49 : Март 11, 2008, 06:40:21 »

TARAKAN внутри класса можно объявлять как методы  класса, так и перегружать операторы.
Например для вектора vector перегрузить оператор operator[].
Чтобы можно было пользоваться:
Код:
vector Foo(10); // создать вектор из 10 элементов
Foo[5] = 3; // третьему элементу вектора присвоить 3
читай инфу.
аналогично operator()
Записан

♪♪ ♫  LET FOREVER BE  ♫ ♪♪ ♫ ♪♪ ♪♪ ♫
TARAKAN
Tifon
Бакалавр
**

Карма: +0/-0
Offline Offline

Пол: Мужской
Сообщений: 134


WWW
« Ответ #50 : Март 11, 2008, 07:00:52 »

В Деструкторе надо сделать цикл, но как туда передать переменную не пойму ... "вводить ее нельзя", а как тогда ?
Допустим есть вот такое ... как передать переменную в деструктор ?
Код: (cpp)
class matrix
{
private:
    int nmas,mmas; 
public:
  double **mas;
  matrix(int n,int m);
  ~matrix();
};
 
matrix::matrix(int n,int m): nmas(n),mmas(m)
{
  int i;
  mas = new double* [nmas];
  for (i=0;i<n;i++)
  {
    mas[i] = new double(mmas);
  }

}

matrix::~matrix()
{
  for (int i=0; i<n; i++)
  {
    delete mas[i];
  }
  delete []mas;
printf("destroyed matrix \n");
}
« Последнее редактирование: Март 15, 2008, 12:11:13 от Романыч » Записан

Студент: По моему легче использовать printf...
EvilMax: Зато cout - это тру! = ))
vimmax
Mодератор
Декан
*****

Карма: +42/-3
Offline Offline

Пол: Мужской
Награды:
лучшая гитара мира
Сообщений: 1713


♪♪ ♫ ♪♪ ♫ ♪♪ ♫ ♪♪


« Ответ #51 : Март 11, 2008, 07:09:14 »

TARAKAN пи-ляя )))
В деструктор нельзя передавать параметры.
Все члены и методы класса видны в деструкторе.
указатели типа double **mas - ненадо делать public.
Т.к. в другом месте программы кто-то может удалить или выделить память по этому указателю.
Вся работа с памятью должна быть скрыта в методах класса.
Записан

♪♪ ♫  LET FOREVER BE  ♫ ♪♪ ♫ ♪♪ ♪♪ ♫
TARAKAN
Tifon
Бакалавр
**

Карма: +0/-0
Offline Offline

Пол: Мужской
Сообщений: 134


WWW
« Ответ #52 : Март 11, 2008, 07:18:21 »

vimmax
Если я правильно понял надо сделать чтото по типу такого
Код: (cpp)
matrix::freemem(int n)
{
  int i;
  for (int i=0; i<n; i++)
  {
    delete mas[i];
  }
  delete []mas;
  printf("\n free memory \n");
}
А деструктор оставить в покое ? = ))
Записан

Студент: По моему легче использовать printf...
EvilMax: Зато cout - это тру! = ))
Артем
sprata
Mодератор
Завкаф
*****

Карма: +40/-5
Offline Offline

Пол: Мужской
Сообщений: 1107


« Ответ #53 : Март 11, 2008, 07:30:57 »


Получается обращение будет вот таким (после заполнения)
*(*rows+i*n+j)=123;

Так как это массив указателей (2-мерный массив) то обращение  будет выглядеть следующим образом:

*( *(rows + i) + j )

*(rows+i) - это 1-ый элемент i-той строки

*(rows + i) + j - двигаемся от 1-ого элемента i-той строки вправо на j элементов

*( *(rows + i) + j ) - ну и наконец разименовуем

все!
Записан
TARAKAN
Tifon
Бакалавр
**

Карма: +0/-0
Offline Offline

Пол: Мужской
Сообщений: 134


WWW
« Ответ #54 : Март 11, 2008, 07:54:16 »

Все компилируется без ошибок (даже предупреждений нету, что странно Смеющийся )
Но когда запускаю приложение вылетает, а точнее идет выделение памяти, заполнение массива, вывод массива на экран, а потом вылетает с такой ошибкой (прикрепил скрин)


Код: (cpp)
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
 
class vektor
&#160; {
&#160; &#160; private:
&#160; &#160; double *x;
 
&#160;  public:
&#160;  vektor(int size);
 
&#160;  ~vektor();
&#160; };
vektor::vektor(int size)
&#160; {
&#160; &#160; x=new double[size];
&#160; &#160; printf("create vector \n");
&#160; }
 
vektor::~vektor()
&#160; {
&#160; &#160; delete x;
printf("destroyed vector \n");
&#160; }
 
 
class matrix
{
private:
&#160; &#160; int nmas,mmas;&#160;
public:
&#160; double **mas;
&#160; matrix(int n,int m);
&#160; zapol(int n,int m);
&#160; freemem(int n);
&#160; ~matrix();
};
 
matrix::matrix(int n,int m): nmas(n),mmas(m)
{
&#160; int i;
&#160; mas = new double* [nmas];
&#160; for (i=0;i<n;i++)
&#160; {
&#160; &#160; mas[i] = new double(mmas);
&#160; }
&#160; printf("create matrix \n");
 
}
 
matrix::zapol(int n,int m)
{
int i,j;
for (i=0; i<n; i++)
for (j=0; j<m; j++)
*(*(mas+i)+j)=i+j;
 
for (i=0; i<n; i++)
{
printf("\n");
for (j=0; j<m; j++)
printf("%.3f&#160; ",*(*(mas+i)+j));
}
 
}
 
matrix::freemem(int n)
{
&#160; int i;
&#160; for (i=0; i<n; i++)
&#160; {
&#160; &#160; delete mas[i];
&#160; }
&#160; delete []mas;
&#160; printf("\n free memory \n");
}
 
matrix::~matrix()
{
&#160; printf("destroyed matrix \n");
}
 
 main(int argc, char *argv[])
{
 int n,m;
&#160; &#160;  n=(int)atof(argv[1]);
m=(int)atof(argv[2]);
matrix a(n,m);
vektor x(n);
a.zapol(n,m);
a.freemem(n);
 
 
getch();
return 0;
}
« Последнее редактирование: Март 15, 2008, 12:13:22 от Романыч » Записан

Студент: По моему легче использовать printf...
EvilMax: Зато cout - это тру! = ))
Alder
Администратор
Проректор
*****

Карма: +331/-16
Offline Offline

Пол: Мужской
Награды:
За II место в конкурсе поэзии (весна-2007)2 место в фотоконкурсе \За II место в фотоконкурсе \3 место в фотоконкурсе \2 место в фотоконкурсе \Лучший знаток музыки 2009Лучший знаток музыки 2010
Сообщений: 11224


just for fun


WWW
« Ответ #55 : Март 11, 2008, 07:56:29 »

TARAKAN, дебаггер в руки. Ставь брейкпоинты и проверяй где именно вываливается, на  каком операторе.
Записан

"There are things known and there are things unknown, and in between are the doors..." (Jim Morrison)
TARAKAN
Tifon
Бакалавр
**

Карма: +0/-0
Offline Offline

Пол: Мужской
Сообщений: 134


WWW
« Ответ #56 : Март 11, 2008, 08:25:16 »

Alder
Буду искать ...


З.Ы. http://kita.org.ua/index.php/topic,4002.msg56885.html#new

(Отправлено в: 11 Марта 2008, 19:03:11)

Ошибка оказалась вот в этом цикле
Код: (cpp)
for (i=0; i<n; i++) 
{
delete mas[i];
}

Если его убрать все нормально, но тогда освобождение памяти неправильное ...
Но если оставить этот цикл, а убрать функцию заполнения/вывода на экран массива, все нормально (массив создается, выделяется память, освобождается память без ошибок и вылетов)

Не могу понять связь между меду заполнением и освобождение памяти ...
Записан

Студент: По моему легче использовать printf...
EvilMax: Зато cout - это тру! = ))
EvilMax
Администратор
Завкаф
*****

Карма: +59/-0
Offline Offline

Пол: Мужской
Сообщений: 1072


Злой и страшный :)


« Ответ #57 : Март 11, 2008, 09:32:13 »

TARAKAN, проверять, проверять и еще раз проверять. Удостоверься (сам, а не с помощью форумчан), что ты не удаляешь чего лишнего. Например, не освобждаешь память, которую не отводил. Или не освобождаешь память дважды.

Не могу понять связь между меду заполнением и освобождение памяти ...
А всё просто. Только для тебя - "Работа с динамической памятью за 5 минут". Смеющийся Итак, правила простые:
Отвёл - освободи.
Не отводил - не освобждай. Смеющийся
Освободил - не вздумай осовбождать еще раз.
Записан

Оптимальная концентрация кофе - это когда код уже дает советы, как его написать, но еще не спорит с тобой и не подкалывает в случае неудач...
---
Существует три способа распространения программного обеспечения: воровство, грабёж и обмен краденым. (c) Неизвестный программист
TARAKAN
Tifon
Бакалавр
**

Карма: +0/-0
Offline Offline

Пол: Мужской
Сообщений: 134


WWW
« Ответ #58 : Март 11, 2008, 09:42:23 »

EvilMax
В функции, где я присваиваю значения, я не отвожу память ... поэтому и не пойму как она может влиять на освобождение памяти ...
Выделение и освобождение памяти в отдельных "частях" находятся ... специально, чтобы не запутаться  Улыбка
Вот программа польностью
Код: (cpp)
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>

class vektor
  {
    private:
      double *x;
 
    public:
      vektor(int size);

     ~vektor();
  };
vektor::vektor(int size)
  {
    x=new double[size];
    printf("create vector \n");
  }
 
vektor::~vektor()
  {
    delete x;
printf("destroyed vector \n");
  }


class matrix
{
private:
    int nmas,mmas; 
public:
  double **mas;
  matrix(int n,int m);
  zapol(int n,int m);
  freemem(int n);
  ~matrix();
};
 
matrix::matrix(int n,int m): nmas(n),mmas(m)
{
  int i;
  mas = new double* [nmas];
  for (i=0;i<n;i++)
  {
    mas[i] = new double(mmas);
  }
  printf("create matrix \n");

}

matrix::zapol(int n,int m)
{
int i,j;
for (i=0; i<n; i++)
for (j=0; j<m; j++)
*(*(mas+i)+j)=123;

for (i=0; i<n; i++)
{
printf("\n");
for (j=0; j<m; j++)
printf("%.3f  ",*(*(mas+i)+j));
}

}

matrix::freemem(int n)
{
  int i;
  for (i=0; i<n; i++)
  {
    delete mas[i];
  }
  delete []mas;
  printf("\n free memory \n");
}

matrix::~matrix()
{
  printf("destroyed matrix \n");
}

 main(int argc, char *argv[])
{
 int n,m;
     n=(int)atof(argv[1]);
m=(int)atof(argv[2]);
matrix a(n,m);
vektor x(n);
a.zapol(n,m);

a.freemem(n);


getch();
return 0;
}
Записан

Студент: По моему легче использовать printf...
EvilMax: Зато cout - это тру! = ))
LazarusLong
Ирландский доброволец
Проректор
*****

Карма: +181/-7
Offline Offline

Пол: Мужской
Награды:
А может я тоже хочу себе награду?
Сообщений: 6133


Ukrainian by birth, Irish by the grace of God


WWW
« Ответ #59 : Март 11, 2008, 09:49:15 »


Отвёл - освободи.
Не отводил - не освобждай. Улыбка
Освободил - не вздумай осовбождать еще раз.
Супер. Ни убавить, ни прибавить! +1.
Записан

Когда ему нужно - он русский, когда нужно - украинец, а когда ему ни хрена не нужно - он ирландец.

"...Он любил говорить факин щит
Когда что-то не так ему
Принимал он свой самый ирландский вид
И кидался трубкой в жену..."
Страниц: 1 2 [3] 4 5 ... 12   Вверх
  Печать  
 
Перейти в:  

Penguins Counter Powered by MySQL Powered by PHP Powered by SMF 1.1.8 | SMF © 2006-2008, Simple Machines LLC Valid XHTML 1.0! Valid CSS! Internetmap
Страница сгенерирована за 0.143 секунд. Запросов: 31.