LINUX.ORG.RU

Конкатенация в С/С++

 


0

2

Приветствую. Возникла задача условно говоря уложить все элементы массива в одну строку. Как делается конкатенация c добавлением в себя самого?

char *total;
gchar *str;
while (g_variant_iter_loop (iter, "s", &str)) {
// -----
total = total + str; // Надо все элементы str уложить в конец total
// -----
g_variant_iter_free (iter);
}

Пробовал через std:string, но оно чото сегфолтится с terminate called after throwing an instance of 'std::bad_alloc', так что лучше все таки простейшими С-функциями.

Благодарю.

★★★★★

Последнее исправление: Dimez (всего исправлений: 1)
Ответ на: комментарий от Psilocybe

Или когда в нескучном язычке конструируется строка, то обходится без strlen?

И чего конструируется: из других строк нескучного языка или из других си-строк нелитералов?

anonymous
()
Ответ на: комментарий от bugfixer

Тех кто пишет на C++ видимо не смущает, потому что делают str += "string" и это каждый раз создаёт новую строку.

Skullnet ★★★★★
()
Последнее исправление: Skullnet (всего исправлений: 1)
Ответ на: комментарий от etwrq

Вы долбоящер? Там всё написано. Я то уж было думал там что-то с переполнением size_t на какой-то гипотетической сегментированной платформе связано. И словесла то какие: «OoB, UB»… Тьфу.

bugfixer ★★★★★
()
Ответ на: комментарий от Skullnet

Тех кто пишет на C++ видимо не смущает

В случае std::string и += там одна destination str capacity которой растёт экспоненциально и квадрата не случается. А в случае std::ostringstream там ещё и изначально что-то порядка 4K преаллоцируют емнип.

bugfixer ★★★★★
()
Ответ на: комментарий от Skullnet

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

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от Skullnet

В этом случае это лишний расход памяти

Не так страшен чёрт как его малютка: это же обычно короткоживущая аллокация. Зато избавляет от проблемы «медленного старта». Я бы не переживал. По крайней мере на моей практике это проблемой никогда не было.

bugfixer ★★★★★
()
Ответ на: комментарий от iron

Можно, но не нужно. Тем более в данном случае. Как там: «просто за время пути собачка могла подрасти». И будет оно там висеть мёртвым грузом после первого же resize, не говоря о лишнем геморрое.

bugfixer ★★★★★
()

путь примерения с лиспом

char *collect(GVariantIter* iter)
{
  // проблемка - нужен буфер неизвестного размера
  // или на каждом шаге реаллоцировать
  // циклы с предрасчётом неспортивно,
  // поэтому путь самурая - рекурсия
  char *buffer=NULL; // тот самый буфер

  void recursion(int offset,GVariant *iter) {
     gchar *str=NULL;
     if (g_variant_iter_loop(iter,"s",&str)) {
        int len=strlen(str);
        recursion(offset+len,iter);
        memcpy(buffer+offset,str,len);
     } else {
        buffer=malloc(offset+1);
        buffer[offset]=0;
     }
  }
  recursion(0,iter);
  return buffer;
}

с руки, как-то так...не проверял ;-)

MKuznetsov ★★★★★
()
Последнее исправление: MKuznetsov (всего исправлений: 1)