LINUX.ORG.RU

Ответ на: комментарий от cvs-255

И действительно, как люди умудряются допускать утечки памяти?

Makefile
()
Ответ на: комментарий от Makefile

Короче, выкладывай полный исходник, без него в топике не веселье.

// вупи голдберг

shty ★★★★★
()
Ответ на: комментарий от Makefile

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

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от cvs-255

Но вот вроде рабочий кусок:

#ifndef __VECTOR_H__
#define __VECTOR_H__

#include "types.h"

#include "memman.h"

/// matrices w x h
class linear
{
	public:
		array2* m;

		/// by default creating zero matrix h0 x w0
		linear(uint w0, uint h0);
		~linear();

		/// multiply matrix by double number 
		linear muln(double n);
	

		/**
			"+" - add matrices;
			"-" - substract matrices;
			"*" - multiply matrices;
		*/
		linear operator + (linear mat);
		linear operator - (linear mat);
		linear operator * (linear mat);
		/**
		"~" - transpose matrix
		*/
		linear operator ~ ();
		/** 
			find a determinant of matrix, if it's square matrix;
			return 0, if matrix is not square
		*/
		double det();
		/**
			invert square matrix;
			return maxtrix of 0 x 0 size, if matrix is not square
		*/
		linear invert();
};

typedef class linear* plinear;

#endif




#include "mvector.h"
#include "memman.h"

#include <math.h>
#include <stdio.h>


/// finding determinant of square array n x n
double Det(array2* ar, uint n)
{

	if (n == 0)
		return 0;
	if (n == 1)
	{
		return ar->m[0][0];
	}
	int p, i, j;
	int a, b, d;
	double c=0;
	p = 1;
	
	ar->link();
	array2 *na = mem_alloc(n-1, n-1);
	for (i = 0; i < n; i++)
	{	

		a = 0; 
		b = 0;
		
		for (a = 1; a < n; a++)
		{
			d = 0;
			for (b = 0; b < n; b++)
			{
				if (b == i)
					continue;
				na->m[a-1][d] = ar->m[a][b];
				d++;
			}
		}
		c += p*Det(na, n-1)*(ar->m[0][i]);
		p = -p;
	}
	na->unlink();
	ar->unlink();
	return c;
}




linear::linear(uint w0, uint h0)
{
	m = mem_alloc(w0, h0);
}

linear::~linear()
{
	if (m != NULL)
		m->unlink();
}



linear linear::operator + (linear mat)
{
	mat.m->link();
	if (m->w != mat.m->w || m->h != mat.m->h)
	{
		mat.m->unlink();
		// error
		linear bad(0,0);
		return bad;
	}
				
	linear res(m->w, m->h);

	uint i, j;
	for (i = 0; i < m->h; i++)
	for (j = 0; j < m->w; j++)
	{
		res.m->m[i][j] = m->m[i][j] + mat.m->m[i][j];
	}
	mat.m->unlink();
	
	res.m->link();
	return res;
}
	
linear linear::operator - (linear mat)
{
	mat.m->link();
	if (m->w != mat.m->w || m->h != mat.m->h)
	{
		mat.m->unlink();
		// error
		linear bad(0,0);
		return bad;
	}
				
	linear res(m->w, m->h);
	uint i, j;
	for (i = 0; i < m->h; i++)
	for (j = 0; j < m->w; j++)
	{
		res.m->m[i][j] = m->m[i][j] - mat.m->m[i][j];
	}
	mat.m->unlink();
	
	res.m->link();
	return res;
}



linear linear::operator * (linear mat)
{
	mat.m->link();
	if (m->w != mat.m->h)
	{
		mat.m->unlink();
		// error
		linear bad(0,0);
		return bad;
	}
				
	uint i, j, k, w1, h1, l;
	w1 = mat.m->w;
	h1 = m->h;
	l = m->w;
	linear res(w1, h1);

	for (i = 0; i < h1; i++)
	for (j = 0; j < w1; j++)
	{
		res.m->m[i][j] = 0;
		for (k = 0; k < l; k++)
			res.m->m[i][j] += m->m[i][k] * mat.m->m[k][j];
	}
	mat.m->unlink();
	
	res.m->link();
	return res;
}

linear linear::muln(double n)
{
	linear res(m->w, m->h);
	uint i, j;
			
	for (i = 0; i < m->h; i++)
	for (j = 0; j < m->w; j++)
		res.m->m[i][j] = m->m[i][j]*n;
	
	res.m->link();
	return res;
}


linear linear::operator ~ ()
{
	linear res(m->h, m->w);
	uint i, j;

	for (i = 0; i < m->h; i++)
	for (j = 0; j < m->w; j++)
		res.m->m[j][i] = m->m[i][j];
	
	res.m->link();
	return res;
}

linear linear::invert()
{
	if (m->w != m->h)
	{
		linear bad(0,0);
		return bad;
	}

	int i, j, a, b, c, d;

	int w = m->w;
	int h = m->h;

	linear res(w, w);


	array2* nm = mem_alloc(w-1, w-1);
	
	double dd = Det(m, w);

	
	for (i = 0; i < w; i++)
	for (j = 0; j < w; j++)
	{
		a = 0; 
		b = 0;
		c = 0;
		d = 0;
			
		for (a = 0; a < w; a++)
		{
			if (a == i)
				continue;
			d = 0;
			for (b = 0; b < w; b++)
			{
				if (b == j)
					continue;
				nm->m[c][d] = m->m[a][b];
				d++;
			}
			c++;
		}
	
		res.m->m[j][i] = Det(nm, w-1)/dd; // transpose i and j
	}
	nm->unlink();
	
	res.m->link();
	return res;
}


double linear::det()
{
	int w = m->w;
	int h = m->h;
	if (w != h)
	{
		//error
		return 0;
	}
	double d = Det(m,w);		
	return d;			
}




cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от cvs-255

Вопрос ребром:

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

-- как приведенный кусок кода соотноситься с реальными приложениями, в которых бывают таки утечки? Реальные приложения - это часто много-много потоков, минимум тысяч десять строк кода, а не пример из учебника на пару экранов.

Вы пробовали ваш менеджер памяти использовать в проекте побольше?

qrck ★★
()
Ответ на: комментарий от qrck

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

В моей задаче поток только один. Потому я не стал писать многопоточный менеджер.

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от qrck

как приведенный кусок кода соотноситься с реальными приложениями

Что ты называешь реальным приложением?

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

Это достаточно условие реальности?

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от cvs-255

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

Это достаточно условие реальности?

Уточню: те здоровые приложения на много десятков тысяч строк кода, в которых реально бывают утечки.

И чем таки плох std/boost::shared_ptr ? При грамотном использовании shard_ptr/weak_ptr, оно позволяет в разы снизить головную боль в плане утечек памяти, и никакой велосипед изобретать не надо. («почему тогда все равно течет?» - то, что написано без shared_ptr разом на использование shared_ptr не перенести и не всегда применимо, да и сам по себе, shared_ptr, без аккуратного использования мозга - все равно не панацея, но если с нуля использовать мозг + shared_ptr, то вероятность утечек можно свести почти к нулю).

qrck ★★
()
Ответ на: комментарий от qrck

Уточню: те здоровые приложения на много десятков тысяч строк кода, в которых реально бывают утечки.

В C++ с его системой ООП утечки могут случаться на казалось бы пустом месте. Собственно поэтому я и сделал так, как сделал.

И чем таки плох std/boost::shared_ptr

Во-первых тянет boost, а объяснять, что я тяну здоровенную библиотеку только для контроля утечек памяти, я не особо хочу.

во-вторых я уже написал то, что написал и переписывать пока не хочу

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от cvs-255

В C++ с его системой ООП утечки могут случаться на казалось бы пустом месте.

Пример можно?

Во-первых тянет boost, а объяснять, что я тяну здоровенную библиотеку только для контроля утечек памяти, я не особо хочу.

Даже до C++11 был std::tr1::shared_ptr, но даже если и тянуть буст - с ним же линковаться не надо. Оно только *.hpp потребует включить, весь код - шаблонами (почти, shared_ptr - точно), так что ничего лишнего не подключиться.

qrck ★★
()
Ответ на: комментарий от cvs-255

Во-первых тянет boost, а объяснять, что я тяну здоровенную библиотеку только для контроля утечек памяти, я не особо хочу.

Вчера начал писать на с++, что ли? Я, кстати, этот вопрос тоже когда-то здесь задавал.

note173 ★★★★★
()
Ответ на: комментарий от cvs-255

Вопросом утечек памяти занялся недавно относительно

Что-то ни разу в треде не было упомянуто заветное слово Valgrind, однако.
Если не придерживаться 100% smart-pointers и контроля доступа в runtime, то альтернатив Valgrind вроде бы как и нету.

backbone ★★★★★
()
Ответ на: комментарий от backbone

Что-то ни разу в треде

Ссори, поисковик сломался...

backbone ★★★★★
()
Ответ на: комментарий от cvs-255

Я про то, что boost — набор очень хорошо разделенных компонент, большая часть которых никакой отдельной сборки вообще не требует, все в заголовочных файлах. Для некоторых вещей (асинхронный ввод-вывод, инструменты для многопоточности) реализация, все-таки, лежит отдельно, но можно просто перенести в свой проект несколько .cpp файлов.

note173 ★★★★★
()
Ответ на: комментарий от Eddy_Em

Знаешь, octave мне очень помогает с лабами и курсачом, да.

luke ★★★★★
()

Действительно. Зачем допускать утечки памяти? Лучше еще раз написать свой GC!

vasily_pupkin ★★★★★
()
Ответ на: комментарий от gods-little-toy

НъТъ. В некоторых случаях хочется явно сказать «а-ну выкинули все, что в этом пуле» и получить немедленное освобождение всяческих ресурсов (открытых соединений, файлов и тд). А не дожидаться, пока ленивый gc дочухает, что $ресурс уже можно освобождать.

GC вроде как не занимается освобождением неуправляемых ресурсов.

encyrtid ★★★★★
()
Ответ на: комментарий от encyrtid

GC вроде как не занимается освобождением неуправляемых ресурсов.

В жабе, де факто, занимается. Если GC занимается *только* памятью, то он тогда становится ограничен, приходится писать свой учет неуправляемых ресурсов. А если у тебя в программе есть свой учет ресурсов, нафига тебе GC?

gods-little-toy ★★★
()
Ответ на: комментарий от gods-little-toy

Я что-то не пойму о чем ты. GC, конечно, очищает память с неуправляемыми ресурсами, но перед этим ты обязан ручками закрыть файлы и пр. В C#, к примеру есть инструкция using для этого:

using(var obj = new SomeDisposableObject())
{
     ...
}
Все содержимое блока будет обернуто в try-catch и по выходе из блока будет вызван метод Dispose объекта в котором должен быть код очистки неуправляемых ресурсов. В последней жабе, ЕМНИП, тоже появилась подобная конструкция. Однако код в Dispose придется все равно писать ручками.

encyrtid ★★★★★
()
Ответ на: комментарий от encyrtid

В последней жабе, ЕМНИП, тоже появилась подобная конструкция. Однако код в Dispose придется все равно писать ручками.

Согласен на 100%, жаба, как ни парадоксально сначала кажеться, куда более предрасположена к утечка ресурсов вроде хендлов файлов или сокетов, C++ в этом плане куда удобнее, а после плюсов - того и гляди, забудешь какой-нибудь flush или close, и все к чертям в Java летит :)

qrck ★★
()
Ответ на: комментарий от cvs-255

u1, u2, w1, w2 вектора (на самом деле матрицы, так как это значения, заданные на сетке), остальное всё скаляры

Reset ★★★★★
()

Ведь удобный менеджер памяти, следящий за выделением и освобождением памяти пишется за пару часов?

overhead очень высокий. Встречаются случаи, когда программа, будучи переписана на C/C++ (частично конечно), начинала работать на порядок быстрее, чем всякие ваши python'ы. Просто за счёт того, что нет никаких проверок и сборок мусора. Расход памяти тоже меньше.

drBatty ★★
()
Ответ на: комментарий от cvs-255

cvs-255

Для моей задачи нужно много умножать матрицы. Это удобнее в C++.

в C++ есть new & delete, их можно перегружать (если хочешь свой менеджер).

drBatty ★★
()
Ответ на: комментарий от cvs-255

cvs-255

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

в чём проблема? для каждого класса ты можешь определить своё new и delete, вот тебе и менеджер. Внутри него можешь организовать просто что угодно, хоть как в жабе, хоть как в пайтоне, а хочешь - как в пхп. Не должна delete освобождать память? Пожалуйста!

drBatty ★★
()

Менеджер памяти спасёт максимум от забытого free. А если брать даже тот же C#, то несмотря на всю его управляемость, память там можно заставить течь очень даже. А уж если COM начать использовать, то вообще трэш, угар и содомия.

Про C++ я даже не упоминаю, там всё ещё страшнее.

Dark_SavanT ★★★★★
()
Ответ на: комментарий от grondek

Объекты должны оставаться на своем месте. И удаляться там где созданы.

Это возможно только разве что копированием целого объекта при передаче в другую часть программы, но это плохо. В общем случае проследить за объектом вручную просто нельзя.

note173 ★★★★★
()
Ответ на: комментарий от Dark_SavanT

Менеджер памяти спасёт максимум от забытого free

Только лишний геморрой будет с функциями, которые выделяют память и возвращают указатель на нее (вроде той же strdup).

Eddy_Em ☆☆☆☆☆
()

По прочтении ника ТС возникло подозрение, что тема будет очередным тупняком. Так и вышло.

max_udoff
()

Как люди допускают опечатки в коде? Ведь на каждой кнопке написана буква! Как люди допускают ошибке в тексте? Ведь есть словари и справочники!

Ну и дальше в том же духе)

Alve ★★★★★
()
Ответ на: комментарий от Alve

Как люди допускают ошибке в тексте?

А ведь правда - как? Мне вот это совершенно непонятно.

Xellos ★★★★★
()
Ответ на: комментарий от Reset

Да как то не очень тормозит.

Будет тормозить - перепишу реализацию матрицы и выделения памяти

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от cvs-255

Придется менять не реализацию, а концепцию. Твою программу можно ускорить в 100 раз. Да, именно в 100 раз и это не шутка и не преувеличение.

Reset ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.