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)
Ответ на: комментарий от Dimez

Просто компилятор бьёт по рукам, а LOR — нет.

i-rinat ★★★★★
()

Кстати, осознают ли любители нескучных язычков, что в случае

while(...)
{
..
 total+=str;
...
}

под капотом такая же пердуха, только без возможности что-либо оптимизировать?

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

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

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

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

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

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

как нуль на конце строки влияет копирование len(p2) в p1, без контороля соответветствия len(p1) и len(p2)?
что вы вообще несёте?

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

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

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

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

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

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

делают str += «string» и это каждый раз создаёт новую строку.

Нет, не создается. Вызывается append(cstr, len). Для строковых литералов len вычисляется на этапе компиляции.

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

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

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

в случае std::ostringstream там ещё и изначально что-то порядка 4K преаллоцируют емнип.

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

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

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

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

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

это же обычно короткоживущая аллокация

Короткоживущие аллокации можно сделать на стеке при помощи alloca().

iron ★★★★★
()
Ответ на: комментарий от 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)
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.