Как правильно освободить память от массива символов, полученных из функции?
Ниже приведен пример. Пытался и через delete str.
Естественно проверяю объем занимаемой памяти в диспетчере. До генерации занимает 440КБ. После генерации объем растет в зависимости от количества символов в тексте ( что логично ).
// Generate string
char * genstr(unsigned int len) {
char chars[] = {'0','1','2','3','4',
'5','6','7','8','9',
'A','B','C','D','E','F',
'G','H','I','J','K',
'L','M','N','O','P',
'Q','R','S','T','U',
'V','W','X','Y','Z',
'a','b','c','d','e','f',
'g','h','i','j','k',
'l','m','n','o','p',
'q','r','s','t','u',
'v','w','x','y','z', '\n', ' ',
'#'
};
char * str = new char [len];
for (unsigned int ix = 0; ix < len; ++ix){
// Первую половину текста мы генерируем без решетки
if (ix < len / 2)
str[ix] = chars[rand() % sizeof(chars) - 1];
else
str[ix] = chars[rand() % sizeof(chars)];
}
return str;
}
int main(int argc, char **argv) {
setlocale(LC_ALL, "rus");
unsigned int X, lines_count = 1, ix = 0;
cout << "Введите длину текста, который необходимо сгенерировать: ";
cin >> X;
char * str = genstr(X);
// Здесь мы что то делаем с этой "строкой"
// Здесь мы пытаемся освободить память
delete [] str;
system("PAUSE");
return 0;
}
если не по делу: не засоряй канал...
Re: Как правильно освободить память от массива символов, полученных из функции?
Здравствуйте, newpy, Вы писали:
N>Как правильно освободить память от массива символов, полученных из функции?
Ну вроде все правильно, нужно через delete [] .
Хотя еще правильнее, когда кто память распределял, тот ее и освобождает.
То бишь вызывающая функция должна передать в вызываемую функцию уже готовый массив. И сама же потом его освободить. Вызывающей функции лучше знать откуда и как распределялась память под массив, и что с ней потом делать.
Здравствуйте, newpy, Вы писали:
N>Как правильно освободить память от массива символов, полученных из функции? N>Ниже приведен пример. Пытался и через delete str.
Всё правильно — если выделяешь new[], значит удаляешь delete[]
Но вообще, понятнее будет выделять и освобождать память на одной стороне:
void genstr(char* str, unsigned int len) {
// заполняем str
}
int main() {
unsigned int X, lines_count = 1, ix = 0;
cout << "Введите длину текста, который необходимо сгенерировать: ";
cin >> X;
char * str = new char[X];
genstr(str, X);
// Здесь мы что то делаем с этой "строкой"
// Здесь мы пытаемся освободить памятьdelete [] str;
system("PAUSE");
return 0;
}
Если программа не учебная, следующим этапом должен быть переход от ручного управления памятью к использованию std::string
N>Естественно проверяю объем занимаемой памяти в диспетчере. До генерации занимает 440КБ. После генерации объем растет в зависимости от количества символов в тексте ( что логично ).
Диспетчер, это диспетчер задач Windows? Насколько я помню, там занимаемая приложением память это какое-то другое значение. И менеджер памяти используемый в CRT может не сразу возвращать память операционной системе.
Re[2]: Как правильно освободить память от массива символов,
Здравствуйте, PM, Вы писали:
PM>Диспетчер, это диспетчер задач Windows? Насколько я помню, там занимаемая приложением память это какое-то другое значение. И менеджер памяти используемый в CRT может не сразу возвращать память операционной системе.
Программа учебная. Действительно, пример помог. Спасибо.
N>char * genstr(unsigned int len) {
N> char chars[] = {'0','1','2','3','4',
N> '5','6','7','8','9',
N> 'A','B','C','D','E','F',
N> 'G','H','I','J','K',
N> 'L','M','N','O','P',
N> 'Q','R','S','T','U',
N> 'V','W','X','Y','Z',
N> 'a','b','c','d','e','f',
N> 'g','h','i','j','k',
N> 'l','m','n','o','p',
N> 'q','r','s','t','u',
N> 'v','w','x','y','z', '\n', ' ',
N> '#'
N> };
static char const chars[] = "012345......#";
// так и записывается компактнее, и не создаётся каждый раз на стеке, а лежит в секции констант
size_t count = sizeof(chars)-1; // исключим концевой нолик из таблицы
N> char * str = new char [len];
char * str = new char [len+1]; // концевой нолик не забываем - иначе это не совсем строка, а просто массив символов
N> for (unsigned int ix = 0; ix < len; ++ix){
N> // Первую половину текста мы генерируем без решетки
N> if (ix < len / 2)
N> str[ix] = chars[rand() % count - 1];
N> else
N> str[ix] = chars[rand() % count];
N> }
str[len] = 0; // вот он, концевой нолик
N> return str;
N>}
C> То бишь вызывающая функция должна передать в вызываемую функцию уже готовый массив. И сама же потом его освободить. Вызывающей функции лучше знать откуда и как распределялась память под массив, и что с ней потом делать.
А какого размера должен быть массив, который передаётся в функцию?
Функция, к примеру, сжатый файл в буфер читает.
Re[3]: Как правильно освободить память от массива символов, полученных из функци
Здравствуйте, borya_ilin, Вы писали:
C>> То бишь вызывающая функция должна передать в вызываемую функцию уже готовый массив. И сама же потом его освободить. Вызывающей функции лучше знать откуда и как распределялась память под массив, и что с ней потом делать.
_>А какого размера должен быть массив, который передаётся в функцию? _>Функция, к примеру, сжатый файл в буфер читает.
Что делать? Гипс снимают! Клиент уезжает! Шеф! Все пропало! Все пропало!
Это разговор отдельный. Как определять. Вариантов масса.
1. Можно использовать WinAPI like стиль. Если присмотреться к функциям WinAPI, то часто используется следующий прием.
Передается указатель на массив для записи результатов чего то, и его размер. В случае успеха функция возвращает число записанных в результирующий массив элементов. Дык вот очень часто оговаривается вариант, что если передать в функцию NULL или максимальный размер элементов в ноль, то она вернет сколько ей надо места для записи.
2. Если случай сложный, или накладный как чтение файлов, то следует передавать не массив в функцию, а объект который сможет сам управлять своим размером, и знает и как это лучше сделать.
Но в любом случае, всегда стоит стараться избегать такого управления памятью, в стиле "Батяня, слышь? Рубит! А я отвожу". Код не лес, и тут такие бубны добром не кончаются. Примеров до упячки можно привести. В контексте стартового топика: в одном месте new, в другом delete. Ну это все хорошо пока какой-нить пьянь супер-пупер-гик не перегрузит new для типа. И подставит собственный аллоктор. На стандартном delete[] словим в общем случае вообще что-угодно, кроме корректного выполнения.
Так что в таких вариантах лучше сразу приучаться четко задавать аллокатор памяти.
А примеров таких проблема масса. Пока все в пределах одного модуля — все прекрасно. Как только в разных, запросто можем получить проблемную ситуацию.
Это конечно все разговоры про архитектуру, а у меня сложилось впечатление, что вопрошающий только разбирается вообще что называется с синтаксисом. Тогда конечно архитектурные разговоры в сторону, но уж и тогда про "чтение сжатого файла" тоже в сторону — это тут и еще больше будет не причем.
А вот про то что, в функцию можно передать массив под данные и его размер, упомянуть стоит. Нехай молодежь учится сразу, пусть хотя бы "держа в уме" про такой прием. Это лучше, чем переучиваться и заново ломать чужие копья.
C>Что делать? Гипс снимают! Клиент уезжает! Шеф! Все пропало! Все пропало! :))):))):)))
К чему столько эмоций?
C>1. Можно использовать WinAPI like стиль.
Это ж надо 2 раза одно и то же читать-распаковывать.
C>2. Если случай сложный, или накладный как чтение файлов, то следует передавать не массив в функцию, а объект который сможет сам управлять своим размером, и знает и как это лучше сделать.
Тут уже не передача вызвающей функцией в вызываемую уже готового массива
Re: Как правильно освободить память от массива символов, полученных из функции?
Здравствуйте, newpy, Вы писали:
N>Как правильно освободить память от массива символов, полученных из функции? N>Ниже приведен пример. Пытался и через delete str.