Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как правильно почистить память ? Продолжение бывшей темы... 
:(
    Опции темы
admsasha
Дата 28.7.2005, 04:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 763
Регистрация: 28.1.2005

Репутация: нет
Всего: 6



вот функция, преобразование int в char...
Код

char *itos(int chislo){
    char* tmp = new char[2048];
    sprintf(tmp,"%i",chislo);
    return tmp;
}


использую как

printf("[%s][%s]",itos(4),itos(6));

Как в этом случае почистить память ?
PM MAIL WWW ICQ Jabber   Вверх
chaos
Дата 28.7.2005, 06:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Серийный программист
****


Профиль
Группа: Завсегдатай
Сообщений: 2979
Регистрация: 7.7.2004
Где: Екатеринбург

Репутация: 6
Всего: 44



в данном случае не как!!!


Добавлено @ 06:33
лутше делать так:
Код

char *s1 = itos(4);
char *s2 = itos(6);

printf("[%s][%s]",s1,s2);

delete[] s2;
delete[] s1;


Это сообщение отредактировал(а) chaos - 28.7.2005, 06:41
PM WWW   Вверх
admsasha
Дата 28.7.2005, 06:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 763
Регистрация: 28.1.2005

Репутация: нет
Всего: 6



Цитата(chaos @ 28.7.2005, 13:32)
когда при чтении программы возникают вопросы, вероятно, ваше решение неудачное


тогда как правильно написать эту функцию ?
PM MAIL WWW ICQ Jabber   Вверх
chaos
Дата 28.7.2005, 06:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Серийный программист
****


Профиль
Группа: Завсегдатай
Сообщений: 2979
Регистрация: 7.7.2004
Где: Екатеринбург

Репутация: 6
Всего: 44



я бы сделал так:
Код

void itos(int n, char *s)
{
  sprintf(s,"%i",chislo);
}

char *s = new char[10];
itos(10, s);
delete[] s;

Добавлено @ 06:48
или можно сделать объектную обертку для char*

Это сообщение отредактировал(а) chaos - 28.7.2005, 06:46
PM WWW   Вверх
admsasha
Дата 28.7.2005, 06:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 763
Регистрация: 28.1.2005

Репутация: нет
Всего: 6



Цитата(chaos @ 28.7.2005, 13:46)
void itos(int n, char *s)
{
  sprintf(s,"%i",chislo);
}

char *s = new char[10];
itos(10, s);
delete[] s;


неее, нужно что бы можно было использовать, так:printf("[%s][%s]",itos(4),itos(6));

так же удобнее чем вводить куча лишних переменных в главной процедуре
Добавлено @ 07:00
Цитата(admsasha @ 28.7.2005, 13:35)
Цитата (chaos @ 28.7.2005, 13:32)
когда при чтении программы возникают вопросы, вероятно, ваше решение неудачное



тогда как правильно написать эту функцию ?

извиняюсь, не то процитировал... спешил, когда писал.....
PM MAIL WWW ICQ Jabber   Вверх
Earnest
Дата 28.7.2005, 07:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Можно просто использовать std::string или MFC::CString и т.д.

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

Цитата(admsasha @ 28.7.2005, 06:54)
нужно что бы можно было использовать, так:printf("[%s][%s]",itos(4),itos(6));

Для этого пример Chaos можно изменить так:
Код

char* void itos(int n, char *s)
{
  sprintf(s,"%i",n);
  return s;
}

НО если тебе это нужно именно для печати, вообще забей и пользуйся стандартным форматированием:
Код

printf("[%d][%d]",4,6);



--------------------
...
PM   Вверх
chaos
Дата 28.7.2005, 07:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Серийный программист
****


Профиль
Группа: Завсегдатай
Сообщений: 2979
Регистрация: 7.7.2004
Где: Екатеринбург

Репутация: 6
Всего: 44



вот еще одно решение:
Код

class CStr
{
    char *s;
public:
    CStr(int n)
        :s(new char[10])
    {
        sprintf(s, "%d", n);
    }

    ~CStr()
    {
        delete[] s;
    }

    operator char*() const
    {
        return s;
    }
};


int main(int argc, char* argv[])
{
    printf("%s\n%s\n", CStr(4), CStr(7));
    return 0;
}


PS класс не завершонный! Просто написан наспех что бы продемонстрировать конкретное решение


и то решение на мой взгляд плохое, тк printf принимает ... после формата, так что еще надо делать явное преобразование (char *)

Это сообщение отредактировал(а) chaos - 28.7.2005, 07:29
PM WWW   Вверх
admsasha
Дата 28.7.2005, 07:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 763
Регистрация: 28.1.2005

Репутация: нет
Всего: 6



Цитата(chaos @ 28.7.2005, 14:18)
вот еще одно решение:


как всё непросто в этом C++... элементарная задача, создает большие проблемы.... smile
PM MAIL WWW ICQ Jabber   Вверх
chaos
Дата 28.7.2005, 08:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Серийный программист
****


Профиль
Группа: Завсегдатай
Сообщений: 2979
Регистрация: 7.7.2004
Где: Екатеринбург

Репутация: 6
Всего: 44



Цитата(admsasha @ 28.7.2005, 07:53)
как всё непросто в этом C++... элементарная задача, создает большие проблемы....  smile

это ты сам себе создаешь проблемы smile
тк можно вывести на экран printf("%d %d\n", 4,6); а ты извращаешься(а за извращения надо платить smile )

Это сообщение отредактировал(а) chaos - 28.7.2005, 08:03
PM WWW   Вверх
admsasha
Дата 28.7.2005, 08:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 763
Регистрация: 28.1.2005

Репутация: нет
Всего: 6



Цитата(chaos @ 28.7.2005, 15:02)
тк можно вывести на экран printf("%d %d\n", 4,6); а ты пытаешься извращаться


я для примера показал, смысл так что из базы с varchar значением берется число, его нужно переделать, сложить с другим числом, и вывести, когда все это делается одной функцией без всяких дополнетельных переменных это очень удобно, еще и в одну строчку можно уместить
printf ("%d \n",stoi(str1)+stoi(str2)); - примерно так
PM MAIL WWW ICQ Jabber   Вверх
chaos
Дата 28.7.2005, 08:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Серийный программист
****


Профиль
Группа: Завсегдатай
Сообщений: 2979
Регистрация: 7.7.2004
Где: Екатеринбург

Репутация: 6
Всего: 44



тогда извращение хранить в базе число в виде строки, хотя бы по тому что
sizeof(1000000) < sizeof("1000000")

хотя дело тво1, на вкус и цвет...

Это сообщение отредактировал(а) chaos - 28.7.2005, 08:14
PM WWW   Вверх
admsasha
Дата 28.7.2005, 08:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 763
Регистрация: 28.1.2005

Репутация: нет
Всего: 6



Цитата(chaos @ 28.7.2005, 15:07)
тогда извращение хранить в базе число в виде строки, хотя бы по томучто sizeof(1000000) < sizeof("1000000")


1. число 3-х значное...
2. может содержаться не только число...
3. мне так удобнее держать в varchar

в том же perl и php никогда проблемы так такой простой задачей не возникало... обидно даже... что с C++ проблемы.. как я заметил он вообще плохо справляется с стринговым типом... даже функциии иначе чем для int приходится писать....
PM MAIL WWW ICQ Jabber   Вверх
chaos
Дата 28.7.2005, 08:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Серийный программист
****


Профиль
Группа: Завсегдатай
Сообщений: 2979
Регистрация: 7.7.2004
Где: Екатеринбург

Репутация: 6
Всего: 44



Цитата

С++ — это на самом деле не столько язык, сколько инструмент для создания ваших собственных языков. Его элегантность заключается отнюдь не в простоте (слова С++ и простота режут слух своим вным
противоречием), а в его потенциальных возможностях. За каждой уродливой проблемой прячется какая-нибудь умная идиома, изящный языковой финт, благодаря которому проблема тает прямо на глазах. Проблема решается так же элегантно, как это сделал бы настоящий язык типа Smalltalk или Lisp, но при этом ваш процессор не дымится от напряжения, а на Уолл-Стрит не растут акции производителей чипов памяти. С++ — вообще не язык. Это мировоззрение или наркотик, меняющий способ мышления.

Джефф Элджер C++ БИБЛИОТЕКА ПРОГРАММИСТА

по сравнению с Perl, PHP

PS хотя сам я не испытываю ни каких проблем, тк знаю перл и очень люблю его

Это сообщение отредактировал(а) chaos - 28.7.2005, 08:26
PM WWW   Вверх
comcon1
Дата 28.7.2005, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

Репутация: 12
Всего: 17



Так-то так, однако уметь то, очем просил создатель темы тоже надо. Хотя это скорее "in a C-face", а не C++. Функции типа
Код

char *a = strdup(b);

как раз и занимаются внутри себя отведением памяти. Потом, если надо, ее можно почистить free(a).
А если сделать printf("%s", strdup(b)) то память отведется, строка напечатается и память сотрется. Поскольку указатель на нее потеряется. Или я что-то неправильно понимаю?
И ему такую же процедуру надо было написать.
Код

char *itos(int chislo){
    char* tmp = (char*)malloc(2048);
    sprintf(tmp,"%i",chislo);
    return tmp;
}

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


--------------------
PM MAIL   Вверх
maxim1000
Дата 28.7.2005, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



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

все тут правильно кроме "память сотрется " smile
выделенную память надо стирать вручную или вызывать какую-то функцию, которая это сделает
само ничего не освободится...
еще как вариант можно делать такую функцию
(только не надо это использовать, это ОЧЕНЬ плохой подход smile - только в качестве демонстрации идеи)
Код

#define ITOS_BUFFER_SIZE 100000
char *itos(int n)
{
  static char Buffer[ITOS_BUFFER_SIZE];
  static int BufferOffset=0;
  char TempBuffer[100];
  int StringLength;
  char *Result;

  sprintf(TempBuffer,"%i",n);
  StringLength=strlen(TempBuffer)+1;
  if(BufferOffset+StringLength>=ITOS_BUFFER_SIZE)
    BufferOffset=0;
  strcpy(TempBuffer,Buffer+BufferOffset);
  Result=Buffer+BufferOffset;
  BufferOffset+=StringLength;
  return Result;
}

в данном случае в начале создается достаточно большой буфер
при каждом вызове в него записывается результат и возвращается указатель на него
строки пишутся друг за другом
после того, как дошли до конца, указатель сбрасывается на начало буфера
таким образом самые первые строки стираются
память выделяется один раз при старте программы (точнее, при первом вызове функции) и все
а значит, никакой утечки не будет smile
Добавлено @ 12:12
Цитата
Таких функций, которые возвращают указатель на отведенную внутри них память в системных вызовах очень много

есть два класса таких функций:
1. возвращают указатель на какую-то область, которая была выделена когда-то и будет освобождена неизвестно когда, эта память используется исключительно для хранения конкретного результата
2. выделяют память и возвращают указатель на него - для них в help-никах обчыно пишут "вы сами должны освободить память от этого указателя"


--------------------
qqq
PM WWW   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0860 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.