EvilMax
Администратор
Завкаф
Карма: +59/-0
Offline
Пол:
Сообщений: 1072
Злой и страшный :)
|
|
« Ответ #40 : Март 06, 2008, 12:44:55 » |
|
artem90, описание массива векторов в матрице не годится. Надо vektor **X. С соответствующей модификацией конструктора матрицы с параметрами. Там внутри кое-что придется добавить Деструктор матрицы, соответственно, тоже усложнится.
|
|
|
Записан
|
Оптимальная концентрация кофе - это когда код уже дает советы, как его написать, но еще не спорит с тобой и не подкалывает в случае неудач... --- Существует три способа распространения программного обеспечения: воровство, грабёж и обмен краденым. (c) Неизвестный программист
|
|
|
vimmax
Mодератор
Декан
Карма: +42/-3
Offline
Пол: Награды:
Сообщений: 1713
♪♪ ♫ ♪♪ ♫ ♪♪ ♫ ♪♪
|
|
« Ответ #41 : Март 06, 2008, 05:57:23 » |
|
artem90 Значит так: Ошибки: 1. cout<<endl<<"Destroyed MATRIX !!!"; пиши так: cout<<"Destroyed MATRIX !!!"<<endl; Потому, что в текст помещается в буффер, но не выводится сразу на консоль. Чтобы вытолкнуть текст из буффера в поток надо или endl или команда flush(). Удобнее ставить endl в конце. Получается при дебаге текст должен печататься на экране, но реально его нету - он лежит в буфере )) 2. Делай конструктор по-умолчанию, без параметров. Он все равно нужен. И добавь метод Init() для дополнительной инициализации. Типа: 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
Пол:
Сообщений: 1107
|
|
« Ответ #42 : Март 06, 2008, 06:06:33 » |
|
EvilMax, описание массива векторов в матрице не годится. Надо vektor **X. С соответствующей модификацией конструктора матрицы с параметрами. Там внутри кое-что придется добавить Деструктор матрицы, соответственно, тоже усложнится. EvilMaxОписание массива векторов в матрице я исправил, но я не совсем понял почему неподходит *X[] - это ведь массив укзаателей, как раз то что мне и нужно (вроде бы ). Деструктор матрицы тоже исправил. А вот с конструктором матрицы никак не соображу, что там надо поменять, вроде и так все работает 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
Пол: Награды:
Сообщений: 1713
♪♪ ♫ ♪♪ ♫ ♪♪ ♫ ♪♪
|
|
« Ответ #43 : Март 06, 2008, 06:18:55 » |
|
3. Указатели сразу инициализируй в NULL (X=NULL) и после delete обратно присваивай в NULL. Пригодится. 4. Если у тебя есть указатель на массив указателей, то для него все равно надо выделить память на массив указателей (стр. 16), а потом по каждому элементу массива снова выделить память для вектора (стр. 20). Удаление наоборот: удаляешь элементы - вектора X[ i ], а потом удаляешь память по Х (стр 35 и 39). 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
Пол:
Сообщений: 1072
Злой и страшный :)
|
|
« Ответ #44 : Март 07, 2008, 10:15:27 » |
|
vimmax, да, увы, у тебя ошибка. Кубик получился Вариант, который сбросил в личку artem90, твоей ошибки не содержит - так что в этот раз обошлось, парень подошел к совету критически. Polyakov прав в том, что к советам надо относиться осторожно. Советующим - 7 раз отмерь, один отрежь. Тем, кому адресованы советы - относиться к ним критически и проверять. Все мы люди-человеки, а людям свойственно ошибаться. хз... но в наше время мы рылись по книгам, по инету, по библиотекам, по знакомым... но не получали готовые ответы из инета (форума)....... и что за программисты получатся поле такого развитияНепонимающий Да, это нехорошо, и вопрос этот поднимался. По-моему, модератор уже как-то отправлял студента из этой тем с вопросом "а что у меня тут не работает?" и совершенно правильно поступал. Поэтому я и не выкладываю полного кода, а ограничиваюсь только общими рекомендациями и консультациями, позволяющими выйти на правильный вариант решения. Был задан вопрос "как это - векторы в матрице?", был дан ответ. Поэтому просьба к форумчанам: не выкладывайте готовые куски кода лабораторных работ. Например, vimmax мог ограничиться фрагментом кода вроде такого: 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
Пол:
Сообщений: 134
|
|
« Ответ #45 : Март 11, 2008, 05:32:26 » |
|
Извиняюсь за непонятный символы в коде, не пойму откуда берутся, при редактировании сообщения все время появляются ... думаю понятно и так ... 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 } Соответственно для освобождения памяти надо сделать вот такую вещ ? Или я чтото путаю ? 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
Пол:
Сообщений: 134
|
|
« Ответ #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
Пол: Награды:
Сообщений: 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
Пол:
Сообщений: 134
|
|
« Ответ #48 : Март 11, 2008, 06:32:41 » |
|
vimmaxЧтобы обращение к элемантам матрицы было человеческим - надо перегрузить operator[] или operator(). И всю работу с указателями организовать внутри. Немного не понял ... как понять перегрузить ... просто я не пойму вобще разницы между [] и () ... А внутри чего именно ?
|
|
|
Записан
|
Студент: По моему легче использовать printf... EvilMax: Зато cout - это тру! = ))
|
|
|
vimmax
Mодератор
Декан
Карма: +42/-3
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
Пол:
Сообщений: 134
|
|
« Ответ #50 : Март 11, 2008, 07:00:52 » |
|
В Деструкторе надо сделать цикл, но как туда передать переменную не пойму ... "вводить ее нельзя", а как тогда ? Допустим есть вот такое ... как передать переменную в деструктор ? 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
Пол: Награды:
Сообщений: 1713
♪♪ ♫ ♪♪ ♫ ♪♪ ♫ ♪♪
|
|
« Ответ #51 : Март 11, 2008, 07:09:14 » |
|
TARAKAN пи-ляя ))) В деструктор нельзя передавать параметры. Все члены и методы класса видны в деструкторе. указатели типа double **mas - ненадо делать public. Т.к. в другом месте программы кто-то может удалить или выделить память по этому указателю. Вся работа с памятью должна быть скрыта в методах класса.
|
|
|
Записан
|
♪♪ ♫ LET FOREVER BE ♫ ♪♪ ♫ ♪♪ ♪♪ ♫
|
|
|
TARAKAN
Tifon
Бакалавр
Карма: +0/-0
Offline
Пол:
Сообщений: 134
|
|
« Ответ #52 : Март 11, 2008, 07:18:21 » |
|
vimmaxЕсли я правильно понял надо сделать чтото по типу такого 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
Пол:
Сообщений: 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
Пол:
Сообщений: 134
|
|
« Ответ #54 : Март 11, 2008, 07:54:16 » |
|
Все компилируется без ошибок (даже предупреждений нету, что странно ) Но когда запускаю приложение вылетает, а точнее идет выделение памяти, заполнение массива, вывод массива на экран, а потом вылетает с такой ошибкой (прикрепил скрин) #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)=i+j; 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; }
|
|
« Последнее редактирование: Март 15, 2008, 12:13:22 от Романыч »
|
Записан
|
Студент: По моему легче использовать printf... EvilMax: Зато cout - это тру! = ))
|
|
|
Alder
|
|
« Ответ #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
Пол:
Сообщений: 134
|
|
« Ответ #56 : Март 11, 2008, 08:25:16 » |
|
AlderБуду искать ... З.Ы. http://kita.org.ua/index.php/topic,4002.msg56885.html#new(Отправлено в: 11 Марта 2008, 19:03:11)Ошибка оказалась вот в этом цикле for (i=0; i<n; i++) { delete mas[i]; } Если его убрать все нормально, но тогда освобождение памяти неправильное ... Но если оставить этот цикл, а убрать функцию заполнения/вывода на экран массива, все нормально (массив создается, выделяется память, освобождается память без ошибок и вылетов) Не могу понять связь между меду заполнением и освобождение памяти ...
|
|
|
Записан
|
Студент: По моему легче использовать printf... EvilMax: Зато cout - это тру! = ))
|
|
|
EvilMax
Администратор
Завкаф
Карма: +59/-0
Offline
Пол:
Сообщений: 1072
Злой и страшный :)
|
|
« Ответ #57 : Март 11, 2008, 09:32:13 » |
|
TARAKAN, проверять, проверять и еще раз проверять. Удостоверься (сам, а не с помощью форумчан), что ты не удаляешь чего лишнего. Например, не освобждаешь память, которую не отводил. Или не освобождаешь память дважды. Не могу понять связь между меду заполнением и освобождение памяти ... А всё просто. Только для тебя - "Работа с динамической памятью за 5 минут". Итак, правила простые: Отвёл - освободи. Не отводил - не освобждай. Освободил - не вздумай осовбождать еще раз.
|
|
|
Записан
|
Оптимальная концентрация кофе - это когда код уже дает советы, как его написать, но еще не спорит с тобой и не подкалывает в случае неудач... --- Существует три способа распространения программного обеспечения: воровство, грабёж и обмен краденым. (c) Неизвестный программист
|
|
|
TARAKAN
Tifon
Бакалавр
Карма: +0/-0
Offline
Пол:
Сообщений: 134
|
|
« Ответ #58 : Март 11, 2008, 09:42:23 » |
|
EvilMaxВ функции, где я присваиваю значения, я не отвожу память ... поэтому и не пойму как она может влиять на освобождение памяти ... Выделение и освобождение памяти в отдельных "частях" находятся ... специально, чтобы не запутаться Вот программа польностью #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
Пол: Награды:
Сообщений: 6134
Ukrainian by birth, Irish by the grace of God
|
|
« Ответ #59 : Март 11, 2008, 09:49:15 » |
|
Отвёл - освободи. Не отводил - не освобждай. Освободил - не вздумай осовбождать еще раз. Супер. Ни убавить, ни прибавить! +1.
|
|
|
Записан
|
Когда ему нужно - он русский, когда нужно - украинец, а когда ему ни хрена не нужно - он ирландец.
"...Он любил говорить факин щит Когда что-то не так ему Принимал он свой самый ирландский вид И кидался трубкой в жену..."
|
|
|
|