Как правильно освободить память от массива символов, полученных из функции?
От: newpy  
Дата: 28.04.15 07:30
Оценка:
Как правильно освободить память от массива символов, полученных из функции?
Ниже приведен пример. Пытался и через 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: Как правильно освободить память от массива символов, полученных из функции?
От: Carc Россия http://www.amlpages.com/home.php
Дата: 28.04.15 07:36
Оценка: +2
Здравствуйте, newpy, Вы писали:

N>Как правильно освободить память от массива символов, полученных из функции?

Ну вроде все правильно, нужно через delete [] .

Хотя еще правильнее, когда кто память распределял, тот ее и освобождает.
То бишь вызывающая функция должна передать в вызываемую функцию уже готовый массив. И сама же потом его освободить. Вызывающей функции лучше знать откуда и как распределялась память под массив, и что с ней потом делать.
Aml Pages Home
Re: Как правильно освободить память от массива символов, полученных из функции?
От: PM  
Дата: 28.04.15 07:54
Оценка:
Здравствуйте, 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]: Как правильно освободить память от массива символов,
От: newpy  
Дата: 28.04.15 08:41
Оценка:
Здравствуйте, PM, Вы писали:

PM>Диспетчер, это диспетчер задач Windows? Насколько я помню, там занимаемая приложением память это какое-то другое значение. И менеджер памяти используемый в CRT может не сразу возвращать память операционной системе.


Программа учебная. Действительно, пример помог. Спасибо.
если не по делу: не засоряй канал...
Отредактировано 28.04.2015 8:43 kaa.python . Предыдущая версия .
Re: Как правильно освободить память от массива символов, пол
От: Кодт Россия  
Дата: 28.04.15 12:06
Оценка:
Здравствуйте, newpy, Вы писали:

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>}
Перекуём баги на фичи!
Отредактировано 28.04.2015 12:08 Кодт . Предыдущая версия .
Re[2]: Как правильно освободить память от массива символов, полученных из функци
От: borya_ilin  
Дата: 28.04.15 12:50
Оценка:
C> То бишь вызывающая функция должна передать в вызываемую функцию уже готовый массив. И сама же потом его освободить. Вызывающей функции лучше знать откуда и как распределялась память под массив, и что с ней потом делать.

А какого размера должен быть массив, который передаётся в функцию?
Функция, к примеру, сжатый файл в буфер читает.
Re[3]: Как правильно освободить память от массива символов, полученных из функци
От: Carc Россия http://www.amlpages.com/home.php
Дата: 28.04.15 13:20
Оценка: +2
Здравствуйте, borya_ilin, Вы писали:

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


_>А какого размера должен быть массив, который передаётся в функцию?

_>Функция, к примеру, сжатый файл в буфер читает.
Что делать? Гипс снимают! Клиент уезжает! Шеф! Все пропало! Все пропало!

Это разговор отдельный. Как определять. Вариантов масса.

1. Можно использовать WinAPI like стиль. Если присмотреться к функциям WinAPI, то часто используется следующий прием.
Передается указатель на массив для записи результатов чего то, и его размер. В случае успеха функция возвращает число записанных в результирующий массив элементов. Дык вот очень часто оговаривается вариант, что если передать в функцию NULL или максимальный размер элементов в ноль, то она вернет сколько ей надо места для записи.

2. Если случай сложный, или накладный как чтение файлов, то следует передавать не массив в функцию, а объект который сможет сам управлять своим размером, и знает и как это лучше сделать.

Но в любом случае, всегда стоит стараться избегать такого управления памятью, в стиле "Батяня, слышь? Рубит! А я отвожу". Код не лес, и тут такие бубны добром не кончаются. Примеров до упячки можно привести. В контексте стартового топика: в одном месте new, в другом delete. Ну это все хорошо пока какой-нить пьянь супер-пупер-гик не перегрузит new для типа. И подставит собственный аллоктор. На стандартном delete[] словим в общем случае вообще что-угодно, кроме корректного выполнения.

Так что в таких вариантах лучше сразу приучаться четко задавать аллокатор памяти.

А примеров таких проблема масса. Пока все в пределах одного модуля — все прекрасно. Как только в разных, запросто можем получить проблемную ситуацию.

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

А вот про то что, в функцию можно передать массив под данные и его размер, упомянуть стоит. Нехай молодежь учится сразу, пусть хотя бы "держа в уме" про такой прием. Это лучше, чем переучиваться и заново ломать чужие копья.
Aml Pages Home
Re[4]: Как правильно освободить память от массива символов, полученных из функци
От: borya_ilin  
Дата: 28.04.15 15:09
Оценка: -2
C>Что делать? Гипс снимают! Клиент уезжает! Шеф! Все пропало! Все пропало! :))):))):)))
К чему столько эмоций?

C>1. Можно использовать WinAPI like стиль.

Это ж надо 2 раза одно и то же читать-распаковывать.

C>2. Если случай сложный, или накладный как чтение файлов, то следует передавать не массив в функцию, а объект который сможет сам управлять своим размером, и знает и как это лучше сделать.


Тут уже не передача вызвающей функцией в вызываемую уже готового массива
Re: Как правильно освободить память от массива символов, полученных из функции?
От: kosmas  
Дата: 05.05.15 12:17
Оценка:
Здравствуйте, newpy, Вы писали:

N>            str[ix] = chars[rand() % sizeof(chars) - 1];


Скобок не хватает.
http://en.cppreference.com/w/cpp/language/operator_precedence
Re: Как правильно освободить память от массива символов, полученных из функции?
От: Zenden Россия  
Дата: 05.05.15 12:20
Оценка:
Здравствуйте, newpy, Вы писали:

N>Как правильно освободить память от массива символов, полученных из функции?

N>Ниже приведен пример. Пытался и через delete str.

Использовать shared_ptr
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.