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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Возврат строки неизвестного размера из функции, работа с выделением памяти в функции 
V
    Опции темы
ama_kid
Дата 6.6.2008, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

Репутация: 2
Всего: 95



Цитата(Mayk @  6.6.2008,  11:45 Найти цитируемый пост)
См аллокаторы в stl
Опять же - поднимаемся до уровня библиотеки шаблонов С++. Оно, конечно, введено в стандарт и все такое, но проблема в том, что во многих компиляторах С, применяемых, допустим, в промышленных контроллерах, она попросту отсутствует. Поэтому интересно узнать решение средствами языка, а не каких-то библиотек (даже если это и трудоёмко). Или наоборот - получить подтверждение, что это невозможно...  smile

Добавлено через 2 минуты и 32 секунды
Цитата(Alek86 @  6.6.2008,  11:55 Найти цитируемый пост)
а если получение длины неотделимо от GetString, то или выделяй большой буфер и пускай функция выдает ошибку, если его оказалось недостаточно или уж выделяй внутри функции и возвращай
Код
struct String {char* p_str; unsigned length;};
Во-во, про второй способ поподробнее пожалуйста... На что должен указывать char* p_str?


--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
Alek86
Дата 6.6.2008, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(ama_kid @  6.6.2008,  11:59 Найти цитируемый пост)
На что должен указывать char* p_str?

на начало строки...


--------------------
user posted image    user posted image
PM MAIL   Вверх
Mayk
Дата 6.6.2008, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



Цитата(mes @  6.6.2008,  15:53 Найти цитируемый пост)
перекосило от конструкции, хотя отработает она без проблем.

delete [] != delete.

Цитата(ama_kid @  6.6.2008,  15:59 Найти цитируемый пост)
Опять же - поднимаемся до уровня библиотеки шаблонов С++. Оно, конечно, введено в стандарт и все такое, но проблема в том, что во многих компиляторах С, применяемых, допустим, в промышленных контроллерах, она попросту отсутствует. Поэтому интересно узнать решение средствами языка, а не каких-то библиотек (даже если это и трудоёмко). Или наоборот - получить подтверждение, что это невозможно..

Ну так вместо шаблонов передавай указатели на malloc/realloc/free  если так заботишся о обобщенности, делов то.


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
ama_kid
Дата 6.6.2008, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

Репутация: 2
Всего: 95



Цитата(Alek86 @  6.6.2008,  12:03 Найти цитируемый пост)
на начало строки... 
А память под строку выделена\освобождена где?



--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
Mayk
Дата 6.6.2008, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



Цитата(ama_kid @  6.6.2008,  16:07 Найти цитируемый пост)
А память под строку выделена\освобождена где?

ДО вызова/а если требутеся - то ВО время. 

Это сообщение отредактировал(а) Mayk - 6.6.2008, 12:09


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
Lazin
Дата 6.6.2008, 12:11 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



можно передавать в функцию не только массив и его размер, но и указатель на функцию изменяющую размер массива...
Код

//тип функции для перераспределения памяти
typedef void* (*realloc_t)(void*, size_t);

char* get_string(char* buf/*out*/, size_t len, realloc_t realloc_)
{
   if (строка buf достаточной длинны)
   {
      записать строку в  buf, 
      return buf;
   }
   в buf слишком мало памяти
   buf = reallock_(buf, новый размер буфера);
   записать строку в buf
   return buf;
}


использовать можно как с динамическим массивом
Код

{
  char* buffer = (char*)realloc(0, 1024);
  buffer = get_string(buffer, 1024, &realloc);
}


так и с массивом размещенным в стеке
Код

void* dummy(void*, size_t)//функция - заглушка
{
 throw std::runtime_error("can't resize array in the stack");
}

{
 char buffer[1024];
 char *p = get_string(buffer, 1024, &dummy);
}

PM MAIL Skype GTalk   Вверх
Alek86
Дата 6.6.2008, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(Mayk @  6.6.2008,  12:05 Найти цитируемый пост)
delete [] != delete.

точно
интересно, какой хороший человек решил их разделять...

Цитата(ama_kid @  6.6.2008,  12:07 Найти цитируемый пост)
А память под строку выделена\освобождена где?

внутри функции
но это только в том случае, если никак не можешь отделить подсчет необходимой длины от GetString (или он просто будет долго работать)


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


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

Репутация: 2
Всего: 95



Цитата(Mayk @  6.6.2008,  12:05 Найти цитируемый пост)
Ну так вместо шаблонов передавай указатели на malloc/realloc/free  если так заботишся о обобщенности, делов то.
Хорошо, а на что передавать указатели в случае new\delete? Аналогом realloc, кстати, в этом случае что у нас является?



--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
Mayk
Дата 6.6.2008, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



Цитата(ama_kid @  6.6.2008,  16:12 Найти цитируемый пост)
Аналогом realloc, кстати, в этом случае что у нас является?

std::copy блин
Цитата(ama_kid @  6.6.2008,  16:12 Найти цитируемый пост)
Хорошо, а на что передавать указатели в случае new\delete?

Цитата(Mayk @  6.6.2008,  15:45 Найти цитируемый пост)
См аллокаторы в stl.  

Цитата(Mayk @  6.6.2008,  15:45 Найти цитируемый пост)
См аллокаторы в stl.  

Цитата(Mayk @  6.6.2008,  15:45 Найти цитируемый пост)
См аллокаторы в stl.  


На что передаются указатели  в аллокаторы?
На что передаются указатели  в аллокаторы?
На что передаются указатели  в аллокаторы?
На что передаются указатели  в аллокаторы?
На что передаются указатели  в аллокаторы?
На что передаются указатели  в аллокаторы?
На что передаются указатели  в аллокаторы?


Это сообщение отредактировал(а) Mayk - 6.6.2008, 12:14


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
ama_kid
Дата 6.6.2008, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

Репутация: 2
Всего: 95



Lazin, привел хороший пример, но к тебе тот же вопрос...


--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
Lazin
Дата 6.6.2008, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(ama_kid @  6.6.2008,  12:12 Найти цитируемый пост)
Аналогом realloc, кстати, в этом случае что у нас является?

новый массив = new[] 
memcpy из старого в новый (если нужно)
delete[] старый массив
PM MAIL Skype GTalk   Вверх
mes
Дата 6.6.2008, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 144
Всего: 250



Цитата(Alek86 @  6.6.2008,  11:55 Найти цитируемый пост)
если функция внутри dll находится

тут два варианта , или "чистый" виртуальный интерфейс, либо С -подход (не смотря на то что прога на С++)



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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



в си алокаторов и new/delete нету, так к слову...
PM MAIL Skype GTalk   Вверх
nirburg
Дата 6.6.2008, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



ama_kid, перед вызовом подобных функций использую предварительное выделение заведомо достаточного объема памяти в стеке, либо хипе (зависит от необходимых размеров). соответственно, память освобождается в той же функции, которая ее выделяла. если максимальный размер возвращаемых данных никак заранее нельзя определить (хотя бы примерно), то, дабы не обременять себя "ментальным геморроем", использую std::string. 

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

поясню:
Код

char *myfunc(char *buffer, int *len)
{
    if (!*len) {
        // определение необходимого размера
        *len = ...;
    } else {
        // работа с буфером
    }
}

void otherfunc()
{
    int buflen = 0;
    char *mybuf;
    
    myfunc(NULL, &buflen);      // buflen = необходимый размер буфера, первый параметр не нужен
    mybuf = new char [buflen];  // или malloc
    myfunc(mybuf, &buflen);
    delete [] mybuf;            // или free
}


как-то так, в общем.

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


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

Репутация: 2
Всего: 95



Цитата(Mayk @  6.6.2008,  12:14 Найти цитируемый пост)
std::copy блин
хмм.. ну тада уж проще использовать с
std::string smile

Добавлено @ 12:20
Цитата(Lazin @  6.6.2008,  12:15 Найти цитируемый пост)
новый массив = new[] 
memcpy из старого в новый (если нужно)
delete[] старый массив 
Повторюсь - что в этом случае с областью видимости в случае использования внутри функции? Ничего, что мы выделяем память, которая будет невалидна потом?
Цитата(Lazin @  6.6.2008,  12:16 Найти цитируемый пост)
в си алокаторов и new/delete нету, так к слову... 
Ну, на самом деле иногда приходится работать со срещенным С\С++ - new\delete есть, а библиотеки шаблонов нет smile
Добавлено @ 12:21
Цитата(nirburg @  6.6.2008,  12:17 Найти цитируемый пост)
как-то так, в общем
В общем-то полностью согласен, и изначальный вопрос родился из мыслей: "а нельзя ли сделать как-нить эдак, чтобы не так?!"


Это сообщение отредактировал(а) ama_kid - 6.6.2008, 12:27


--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
Страницы: (4) Все 1 [2] 3 4 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.1404 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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