Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.08.2015, 01:13   #1
polin11
Форумчанин
 
Регистрация: 07.06.2015
Сообщений: 164
По умолчанию утечка памяти

Взял листинг кода из книги Стивен Прата Язык программирования С++.
Меня терзают смутные сомнения нет ли здесь утечки памяти, указатель

определенный в функции buildstr в куче, не очищается в ней. Очищается

указатель ps на результат функции. Адреса &ps!=&pstr, указатели указывают на
на одну область. Хочу в своей программе сделать похожий подход, функция

возвращает указатель на символьный массив

Код:
#include<iostream>
using namespace std;
char* buildstr(char c, int n);
int main()
{
   int times;
   char ch;
   cout<<"Enter a character";
   cin>>ch;
   cout<<"Enter an integer";
   cin>>times;
   char* ps=buildstr(ch, times); 
   cout<<ps <<"\n";
   delete [] ps;                  //высвобождение памяти
   ps=buildstr('+', 20);          // повторное использование указателя
   cout<<ps <<"DONE" <<ps <<"\n";
   delete [] ps;                   //высвобождение памяти
   return 0;
}

char* buildstr(char c, int n)
{
   char* pstr=new char[n+1];
   pstr[n]='\0';
   while(n-->0)
        pstr[n]=c;
   return pstr;
}

Последний раз редактировалось Stilet; 18.08.2015 в 09:00.
polin11 вне форума Ответить с цитированием
Старый 18.08.2015, 06:52   #2
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,964
По умолчанию

Код:
char* ps=buildstr(ch, times); 
 cout<<ps <<"\n";
 delete [] ps; //высвобождение памяти
 ps=buildstr('+', 20); // повторное использование указателя
 cout<<ps <<"DONE" <<ps <<"\n";
 delete [] ps; //высвобождение памяти
Так делать нельзя. Вы создали указатель ps а потом его удалили из мамяти. Повторное использование этого указателя невозможно т.к. он уничтожен.
Если нужно использовать указатель несколько раз, его нужно не удалять, а очищать, например так: ps.clear; (для статического указателя) или ps->Clear; для объекта. Но в этом случае должен быть создан объект например так:
char *ps = new buildstr(ch, times);
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder
Smitt&Wesson вне форума Ответить с цитированием
Старый 18.08.2015, 07:03   #3
Krasiosoft
Форумчанин
 
Аватар для Krasiosoft
 
Регистрация: 01.06.2015
Сообщений: 497
По умолчанию

polin11, указатель на char - это просто адрес, где будет лежать строка.

В данном случае, после каждого вызова buildstr нужно освобождать память через delete[]
Если помог, буду очень благодарен за Ваш отзыв (весы в левой нижней части сообщения).

Последний раз редактировалось Krasiosoft; 18.08.2015 в 07:06.
Krasiosoft вне форума Ответить с цитированием
Старый 18.08.2015, 07:18   #4
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,964
По умолчанию

Цитата:
Сообщение от Krasiosoft Посмотреть сообщение
polin11, указатель на char - это просто адрес, где будет лежать строка.

В данном случае, после каждого вызова buildstr нужно освобождать память через delete[]
Не запутывайте человека. Он и так запутался.

char ch - это объявление указателя как строки с нулём в конце. Очистка строки ch = "";

char *ps = buildstr(ch, times); - объявление статического указателя на объект. Доступ к элементам объекта через точку (ps.clear).

char *ps = new buildstr(ch, times); - указатель на динамический объект. Доступ к объекту ps->Clear;

delete [] ps; - уничтожение объекта. Т.е. Полное освобождение от него сегмента памяти. Дальнейшее обращение к нему невозможно по причине отсутствия самого объекта.
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder
Smitt&Wesson вне форума Ответить с цитированием
Старый 18.08.2015, 07:40   #5
220Volt
Форумчанин
 
Регистрация: 14.12.2012
Сообщений: 671
По умолчанию

Smitt&Wesson, что за ерунду пишите? Налицо незнание элементарных основ. Не торопитесь советы раздавать.
220Volt вне форума Ответить с цитированием
Старый 18.08.2015, 07:40   #6
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Цитата:
char ch - это объявление указателя как строки с нулём в конце.
Это один символ
Цитата:
Очистка строки ch = "";
Это вообще не скомпилируется, ибо каст из const char* в char. Но даже, если бы ch была указателем, то это всё равно никакая не очистка, это просто "перенацеливание" указателя на строковый литерал, который где-то в статике сохранен.
Цитата:
char *ps = buildstr(ch, times); - объявление статического указателя на объект. Доступ к элементам объекта через точку (ps.clear).
Указатель не статический, а автоматический. buildstr функция. В ней будет выделен огрызок памяти, адрес которого эта функция и вернет. "Сохраняется" адрес в указателе ps. Т.к. ps - голый указатель, то ни о какой точке вообще речи быть не может. Ну и никакого Clear рет тоже.
Цитата:
delete [] ps; - уничтожение объекта. Т.е. Полное освобождение от него сегмента памяти. Дальнейшее обращение к нему невозможно по причине отсутствия самого объекта.
К удаленному объекту невозможен, но никто не мешает "перенацелить" указатель на другой объект.

P.S. мне кажется, Вы языки перепутали ну или просто троллите новичка

Последний раз редактировалось Croessmah; 18.08.2015 в 07:50.
Croessmah вне форума Ответить с цитированием
Старый 18.08.2015, 09:02   #7
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,964
По умолчанию

Цитата:
Сообщение от Croessmah Посмотреть сообщение
P.S. мне кажется, Вы языки перепутали ну или просто троллите новичка
Просто с марта месяца ни одной строчки не написал (ремонт в квартире). Кое-что подзабылось. А с чарами вообще лет пять уже не работал. Так, что скорее всего, сильно-сильно забыл что там к чему.
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder
Smitt&Wesson вне форума Ответить с цитированием
Старый 18.08.2015, 12:17   #8
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,120
По умолчанию

polin11

Взял листинг кода из книги Стивен Прата Язык программирования С++.
Меня терзают смутные сомнения нет ли здесь утечки памяти


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

Хочу в своей программе сделать похожий подход

не стоит, для с++ код довольно коряв, нужно вручную следить за указателями.
возможности языка позволяют гораздо больше, чем постоянно подчищать чью-то память)
Rififi вне форума Ответить с цитированием
Старый 18.08.2015, 12:45   #9
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,520
По умолчанию

Подход плохой, применять его не нужно на практике.
Или пользуйтесь правилом: кто выделил память, тот её и освободил или пользуйтесь умными указателями или классами "обёртками" типа string, vector,...
Вас уже этот мелкий пример ввёл в заблуждение, а на большом проекте совсем запутаетесь где за какой функцией нужно прибрать память.
В данном случае предпочтительнее передавать в функцию уже выделенный кусок памяти с указанием размера этого куска, т.е.:
Код:
char* buildstr(char *buf, int buf_size, char c, int n);
параметр n можно выкинуть и вместо него пользовать buf_size, тут уже зависит от задачи. Обращаю также внимание, что тут уже следует возвращать из функции параметр buf (просто return buf в конце) или поменять возврат на void, тоже зависит от функции и вариантов её использования.
pu4koff на форуме Ответить с цитированием
Старый 18.08.2015, 17:13   #10
Krasiosoft
Форумчанин
 
Аватар для Krasiosoft
 
Регистрация: 01.06.2015
Сообщений: 497
По умолчанию

Цитата:
Сообщение от pu4koff Посмотреть сообщение
Подход плохой, применять его не нужно на практике.

Или пользуйтесь правилом: кто выделил память, тот её и освободил
Такой подход встречается в библиотеках написанных на чистом Си, но там в основном создают и функцию freestr, которую нужно вызывать после buildstr. Но что в нем плохого?
Если помог, буду очень благодарен за Ваш отзыв (весы в левой нижней части сообщения).
Krasiosoft вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Утечка памяти OmegaBerkut Общие вопросы Delphi 21 09.04.2015 22:12
утечка памяти Кудаив Помощь студентам 1 30.04.2012 18:18
Утечка памяти forivanb Общие вопросы Delphi 4 11.04.2012 15:28
Утечка памяти ZvEr_HaCkEr Свободное общение 13 24.09.2010 19:30
утечка памяти в С++ vengo Общие вопросы C/C++ 9 10.06.2008 21:24