Junior
Статус: Не в сети Регистрация: 26.01.2008 Откуда: Ukraine
Вопрос по шаблонам STL: необходимо реализовать сложение двух матриц с помощью шаблона. Можете пожалуйста подкинуть информацию по данной теме, а то в интернете ничего толкового найти пока не могу
Member
Статус: Не в сети Регистрация: 10.12.2007 Откуда: Санкт-Петербург
Всем доброго времени суток. Функция находит остаток от деления 2 многочленов. В самой ф-и он находится верно, но происходит 1 неприятная вещь.
Код:
int *remaind(int * const p, int len1, int *p22, int len2, int *rem, int &len3){ int *p1 = new int [len1]; int *p2 = new int [len2]; int k= len1-1; for (int i=0; i<len1; i++) p1[i] = p[i]; for (int i=0; i<len2; i++) p2[i] = p22[i]; for (int i=0; i<len1/2; i++) { int temp = p1[i]; p1[i] = p1[k-i]; p1[k-i] = temp; } k = len2-1; for (int i=0; i<len2/2; i++) { int temp = p2[i]; p2[i] = p2[k-i]; p2[k-i] = temp; } int *ptr1; ptr1 = p1; int ii=0; while (len1>=len2) { int del = (int)(*ptr1/ *p2); for (int i=0; i<len2; i++) *(ptr1+i) -= del * p2[i]; len1--; ptr1++; } rem = ptr1; len3 = len1; delete [] p1; delete [] p2; return rem; }
Стоит только освободить память из-под p2, как удаляется все, что было в rem, но так быть не должно. Значит, p2 и rem в этот момент имеют одинаковые значения адреса. А вот как это исправить, не знаю
_________________ Семь бед, один Reset. 95, 98 - это количество багов. В пpоцентах... DCN - наше все
Advanced member
Статус: Не в сети Регистрация: 30.08.2003 Откуда: Санкт-Петербург
manya 1) в таких функциях лучше ничего не return'ить, а возвращать значения через аргументы-указатели. И возвращают обычно код ошибки (вроде как 0 - все ОК, остальное - конкретные коды) или кол-во возвращаемых элементов. 2)
Цитата:
Стоит только освободить память из-под p2, как удаляется все, что было в rem, но так быть не должно.
что-то напутано с указателями
Цитата:
Значит, p2 и rem в этот момент имеют одинаковые значения адреса.
не факт.
Цитата:
А вот как это исправить, не знаю
в дебаггере (отладчике) для начала запустить. И внимательно следить за указателями. Легко может оказаться, что один указатель налезает на пространство, адресуемое другим.
_________________ {:€ дед в законе :-) нородный окодемег почетный пользователь OpenSuSE 11.3 Ремонт и модернизация ноутбуков IBM (Lenovo) ThinkPad
Member
Статус: Не в сети Регистрация: 10.12.2007 Откуда: Санкт-Петербург
Цитата:
Легко может оказаться, что один указатель налезает на пространство, адресуемое другим.
. Так и есть. Дело в том, что указатель ptr1 ходит по массиву и всегда внутри него, а значит освобождая память из под p1, я убиваю rem, что совершенно мне не нужно. Можно было бы копировать нужный измененный кусок p1, а потом возвращать на него указатель, но вот только тогда получится, что я буду возвращать указатель на локальную переменную из функции, что тоже не есть хорошо
Добавлено спустя 20 минут 22 секунды: В этом-то и весь вопрос
_________________ Семь бед, один Reset. 95, 98 - это количество багов. В пpоцентах... DCN - наше все
ты просто не совсем понимаешь, где и как память выделяется
вот для такой конструкции
Код:
int *p1 = new int [len1];
на самом деле происходит сразу 2 выделения памяти: из кучи выделяется len1 байт данных, и в стеке размещается непосредственно указатель, и занимает там sizeof(int*) байт, 4 для 32битных систем и 8 для 64битных. когда ты в конце функции делаешь return стек сворачивается и значения всех локальных переменных, которые были там размещены, ессно, портится, значения входных переменных тоже портятся. НО! при этом кучу никто не трогает. как у тебя было выделено len1 байт - так они и остались выделенными, и всё, что там было записано никуда не пропадает. даже если будет уничтожен последний указатель на эту область данных - она останется выделенной до тех пор, пока процесс не помрёт. поэтому, в твоём случае надо просто выделить ещё один кусок длины len3 для rem и скопировать туда значения. а потом, в той функции, откуда позвали remaind(), не забыть эту память подчистить.
почитай на тему heap, malloc, new, new[] (последние 3 делают примерно одно и то же), ну и ещё про стандарт вызова процедур stdcall, чтобы картина стала совсем понятной.
Добавлено спустя 2 минуты 10 секунд: ну и ответ на вопрос: в своей функции ты возвращаешь не локальную переменную, а указатель на кусок памяти, который выделен в куче.
Junior
Статус: Не в сети Регистрация: 26.01.2008 Откуда: Ukraine
Помогите пожалуйста с векторами. Надо инициализировать двумерные вектора в классе. Но у меня не получается, юзал поиск, ничего найти не смог. Смог найти только про одномерные вектора, но про двумерные ничего нет. Заранее спасибо.
Код:
#include <iostream> #include <vector> #include <conio.h> using namespace std;
class Addition{ protected: int M; int N; int A; int B; int i; int j;
Помогите пожалуйста с векторами. Надо инициализировать двумерные вектора в классе. Но у меня не получается, юзал поиск, ничего найти не смог. Смог найти только про одномерные вектора, но про двумерные ничего нет. Заранее спасибо.
Junior
Статус: Не в сети Регистрация: 26.01.2008 Откуда: Ukraine
progn Проинициализировать двумерный вектор в классе. Именно в классе, как просто инициализировать я нашел до этого, спасибо, но в классе такая инициализация не работает.
BMWM3GTR так ты выражайся точнее и правильнее, тебе похоже нужны matrix1,... не как локальные переменные в функции create_matrix, а как члены класса
определи vector <vector <int> > matrix1;
как член класса
а инициализировать можно в конструкторе, в списке инициализации
Addition(int N, int M) : matrix1(N,vector<int>(M)) { }
или в ручками, в любом методе
matrix1->resize(N); for (int i = 0; i < N; i++) matrix1[i].resize(M);
там кстати по ссылке был похожий способ, только через push_back for ( int i = 0; i < 5; i++ ) { items.push_back ( vector<int>() );
ps дизайн программы у тебя кривой, правильнее сделать класс матрица, переопределить операцию "+" (при неподходящем размере операндов она выбрасывает exception (можно просто std::runtime_error), а также ввод, вывод в поток.
Может при вставках кода (например больше 3 строк) использовать например: http://dpaste.com , http://paste.org.ru , http://pastebin.ca Чтобы пользователи знали где размещать код ссылки на них прикрепить в первый топик и сделать, чтобы он он на каждой странице отображался.
Junior
Статус: Не в сети Регистрация: 26.01.2008 Откуда: Ukraine
progn Да, именно так. Именно то что нужно. Спасибо, работает.
п.с. Согласен что так лучше, но это просто задание с обязательным использованием STL, поэтому...вот так сделал. Хотя за идею переопределения "+" спасибо.
Member
Статус: Не в сети Регистрация: 20.03.2009 Откуда: Санкт-Петербург
Приветствую. Помогите пожалуйста с "небольшой" проблемой. Ситуация вот какая: дома стоит visual studio 2008 PE, а там,где сдаю лабы -VS 6.0. Она настолько древняя,что не работают дружественные функции. В смысле программа ругается,что мол пытаетесь получить доступ к закрытым членам класса. Вот описание класса
Код:
class IntSet { int *maselm; int kolelm; public: IntSet(); IntSet(char*); IntSet(const IntSet &tmp); ~IntSet(); void vvod(char*); void vuvod(); IntSet operator=(IntSet); IntSet operator+(IntSet); IntSet operator+(int); IntSet operator-(IntSet); IntSet operator-(int); void operator+=(IntSet); void operator-=(IntSet); int operator==(IntSet); int operator!=(IntSet); int operator>(IntSet); int operator<(IntSet); int operator>=(IntSet); int operator<=(IntSet); IntSet operator*(IntSet); ostream &func(ostream &stream); ostream &operator<<(ostream &stream); // friend ostream &operator<<(ostream &stream,const IntSet tmp); // friend istream &operator>>(istream &stream,IntSet &tmp); private: int check_to_add(int number); void add_to_mas(int number); void del_from_mas(int); };
Помогите прегрузить операторы вывода <<. Ввод я надеюсь сам уж тогда смогу. Вот обычная функция вывода
Но при компиляции конструкция типа cout<<p не работает. Пишется бинарный '<<': не найден оператор, принимающий правый операнд типа 'IntSet' (или приемлемое преобразование отсутствует) Я тока начал разбираться с с++, с уже вроде как знаю. Не пинайте сильно, если есть нелепая ошибка
_________________ Задачи бывают простыми и очень простыми...
Про одинаково и & я догадываюсь,просто когда уже пытался по-разному. В настоящий момент пытаюсь реализовать всё без friend ф-ии, и в связи с этим они закомментированы. Так что вопрос в силе, как перегрузить <<, не используя дружественные ф-ии.
Добавлено спустя 3 часа 2 минуты 15 секунд: Вопрос снят) Всё сделал. Завтра сдавать буду
_________________ Задачи бывают простыми и очень простыми...
подскажите,плз, как можно средствами C++ менять размер консоли? это просто делается например в VC++(для СLR приложений), но надо сделать это в GCC(IDE Netbeans)
Advanced member
Статус: Не в сети Регистрация: 30.08.2003 Откуда: Санкт-Петербург
iliax Стандартными средствами C++ - никак. В остальном - нужно искать стандартную виндовую ф-цию для управления консольным окном. MSDN в помощь См. также http://www.cplusplus.com/forum/beginner/1481/
_________________ {:€ дед в законе :-) нородный окодемег почетный пользователь OpenSuSE 11.3 Ремонт и модернизация ноутбуков IBM (Lenovo) ThinkPad
можно и в линуксах, точно так же как и в винде, находишь исковое окно и меняешь размер. Но это глупость и извращение, во первых никакого окна оконной системы может и не быть, а во вторых это неправильно идеологически, сама идея консольных приложений в их отвязанности от GUI, в том что стандартные потоки можно переопределять и можно соединять несколько приложений пайпами (вывод одного, на ввод другого).
Если вообще возникла такая потребность, то надо было писать оконное приложение.
Еще в случае винды можно поменять свойство ярлыка.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения