Javier Luis Lopez Ответов: 2

Выносливость памяти массива, выделенной во внешней функции


Я не делаю внешнего выделения массивов или классов, потому что не знаю, правильно ли это делать и будет ли распределение NAW переменной доступно вне функции.
Вопрос: Правильно ли выделять его во внешнюю функцию?

Что я уже пробовал:

Этот код работает в windows:
void external_memory_allocation_function(char **data,int size)
{
	*data=new char[size];
}


void main()
{
	char *data=NULL;
	int size=100000;
	external_memory_allocation_function(&data,size);
	char *data2=new char[size];
	for (int i=0;i<size;i++)
		data2[i]=data[i]=(char) i;
	delete[] data;
	delete[] data2;
}

Javier Luis Lopez

Я предполагаю, что выделение памяти остается до тех пор, пока оператор delete[] не уничтожит его.

2 Ответов

Рейтинг:
17

OriginalGriff

Ты можешь это сделать, но.....
Проблема в том, когда дело доходит до освобождения памяти.
Поскольку выделение "скрыто" в функции, не очевидно, что оно должно быть удалено, и вполне возможно, что функция может быть изменена, чтобы не выделять каждый раз - она может использовать глобальный массив или частичное выделение из большего куска памяти, например, - и тогда ваша операция удаления завершится неудачей. Или же одна и та же память может быть использована несколькими вызовами, скажем, - и тогда ваше удаление преждевременно избавится от памяти.

Лично я предпочел бы видеть либо "парные" функции, либо лучше выделение, выполняемое в той же функции, которая удаляет память, когда она закончена.


Javier Luis Lopez

Вы правы. Мне нравится скрывать переменную в классе, выделять ее в конструкторе и освобождать в деструкторе.
Исключение составляет случай, когда вы не знаете начального размера переменной, как, например, в функции, которая читает файл, но вы должны позаботиться о том, чтобы не использовать ту же переменную для других целей и удалить ее правильным образом.

Рейтинг:
12

Jochen Arndt

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

Два дополнительных Примечания:

Нет никакой необходимости проверять наличие NULL указатель при вызове delete. Осуществление delete будет делать это тоже и просто ничего не делает, когда указатель находится NULL.

При удалении массива следует использовать delete[] оператор:

delete[] data;

Вы также можете взглянуть на интеллектуальные указатели C++ :
auto_ptr-ссылка на C++ [^]
shared_ptr-ссылка на C++ [^]
ссылка unique_ptr - C++ [^]
ссылка weak_ptr - C++ [^]


Javier Luis Lopez

Спасибо, я отредактировал delete [] вместо delete.
Также я удалил чек на null. Начальное значение *data=NULL позволяет использовать delete[] без ошибок.