LINUX.ORG.RU

динам. память в ц++


0

0

Я не программист, но пришлось взяться за вещи на c++; уровень у меня нулевой, прошу это учесть при объяснениях :-)
Дело такое: если я имею что-то вроде:
if (foo)
{
   float *bar = new float [runtime_N];
   ...
  -> тут <-----------------------|                      
}                                |
                                 |
то                               |
delete [] arr;                   |  
должно стоять там, правильно? -- |
(в конце блока)

Второй вопрос: если вышестоящий блок вызывается многократно,
а deletом там и не пахло, то рано или поздно не останется памяти и программа упадет? (Догадываюсь, что да. Этот ли случай называется memory leak?)

И третий: освобождается ли занятая память после завершения программы (если не был вызван delete), или при следующем запуске память все еще недоступна?
anonymous

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

2 - да. это memory leak.

3 - освобождается

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

Наверное, наивный вопрос, но, чисто теоретически - какой смысл оставлять память зарезервированной, если указателем на неё уже не воспользоваться? Или на уровне компилятора это нетривиальная задача?

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

> Или на уровне компилятора это нетривиальная задача?

на уровне рантайма это решается с помощью garbage collection

на уровне компиляции это нестандартная задача, потому что вызов любой фунции f(указатель) требует анализа этой функции на предмет того что она не запоминает где-нибудь этот указатель (или указатель+смещение)

dilmah ★★★★★
()

>float *bar = new float [runtime_N];

пиши так

std::vector<float> bar(runtime_N);

и память сама освободиться в конце функции

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

Да, мне понравилась STL, даже без мусорщика очень удобно. Но в моём случае её к сожалению нельзя использовать.

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

>Да, мне понравилась STL, даже без мусорщика очень удобно. Но в моём >случае её к сожалению нельзя использовать.

написать аналог std::vector дело пары минут, если брать только индиксацию, конструктор и деструктор.

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

>написать аналог std::vector дело пары минут

Для тебя, может быть :-) Мне такое вряд ли по зубам на данный момент, и не хочется отвлекаться на постороннее, есть другие приоритеты.

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

>Наверное, наивный вопрос, но, чисто теоретически - какой смысл оставлять память зарезервированной, если указателем на неё уже не воспользоваться? Или на уровне компилятора это нетривиальная задача?

На уровне компилятора она алгоритмически не решается. Точнее нельзя, например, алгоритмически узнать есть ли в программе утечка или нет. Можно взять какой либо ЯП c GC, но там тоже некоторое подобие утечек бывает (если забыть занулить указатель на не нужную по смыслу программы память).

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

>и не хочется отвлекаться на постороннее, есть другие приоритеты.

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



> дело пары минут

Ну неужели что-нибудь типа этого трудно написать:
#include <cstdlib>
#include <cstdio>

template<typename T>
class MyVector {
public:
	explicit MyVector(size_t s): size_(s) {
		data_ = new T[size_];
	}
	T& operator[](size_t i) {
		return data_[i];
	}
	size_t size() const { return size_; }
	~MyVector() {
		delete []data_;
	}
private:
	T *data_;
	size_t size_;
};

int main()
{
	MyVector<float> v(10);
	for (size_t i = 0; i < v.size(); ++i) {
		v[i] = i;
		printf("%f ", v[i]);
	}
	printf("\n");
	return EXIT_SUCCESS;
}

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

Утечки памяти можно отлавливать - valgrind, electric fence и прочая. Другое дело, что это делается на этапе отладки, т.к. велики накладные расходы.

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

А где конструктор копии, оператор присваивания, приведение к указателю, константный оператор [], виртуальный деструктор и тыды и тыпы.

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

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

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

>...виртуальный деструктор...

зачем в классе-значении виртуальный деструктор о_О?...

>Не говоря уже про возможность указания размера массива в качестве параметра шаблона.

Это уже не vector.

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

>delete[] &(v[0]);

Кто ж тебе после такого доктор? Инкапсуляцию нарушаем-с... А вообще (ИМХО) доступ по индексу для не-POD типов - ересь...

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

> зачем в классе-значении виртуальный деструктор о_О?...

Откуда следует, что это класс-значение?

> Это уже не vector.

Это оптимизированная версия RO вектора.

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

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

>Ну неужели что-нибудь типа этого трудно написать:

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

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

> Вобщем это дело либо далеко не пары минут, либо получается вот такой вот мутант, ломающийся от каждого пука.

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

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

> Так все равно придется освобождать память (уничтожать вектор), разве нет? Поправьте меня, если не так - я просто не знаю, как работают деструкторы

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

> И потом не реализована ни одна функция.

Там определен operator[]

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

>Откуда следует, что это класс-значение?

А что это по-вашему? Интерфейс?... Или класс, открыто наследующий интерфейс?... Или он предназначен для открытого наследования?...

>Это оптимизированная версия RO вектора.

%)... При чём тут r/o?... Вы наверно имели в виду "вектор фиксированной (статической) длинны"? Так это, как я писал выше, не вектор, а array (см. например boost.array)...

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

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

Продолжим...

>приведение к указателю

Это не есть хорошо. Может привести к неочевидным последствиям (см. книгу Дьюхерста "Скользкие места C++"). Если уж так нужно получить указатель, пользуйтесь адресом первого элемента, или, в крайнем случае, добавьте ещё один метод в интерфейс.

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

>а smart pointers можно ? тогда std::auto_ptr<>...

А как у него с хранением динамических массивов (иметься в виду разница delete и delete[])?...

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