[devel] конкатенация строк

=?iso-8859-1?q?led_=CE=C1_altlinux=2Eru?= =?iso-8859-1?q?led_=CE=C1_altlinux=2Eru?=
Ср Ноя 28 22:59:24 MSK 2007


Wednesday, 28 November 2007 19:34:23 Alexey Tourbin написав:
> On Wed, Nov 28, 2007 at 07:35:18PM +0300, Alexey Tourbin wrote:
> > > > UINT4 rc_map2id(char *name)
> > > > {
> > > >         struct map2id_s *p;
> > > >         char ttyname[PATH_MAX];
> > > >
> > > >         *ttyname = '\0';
> > > >         if (*name != '/')
> > > >                 strcpy(ttyname, "/dev/");
> > > >
> > > >         strncat(ttyname, name, sizeof(ttyname));
> > > >
> > > >         for(p = map2id_list; p; p = p->next)
> > > >                 if (!strcmp(ttyname, p->name)) return p->id;
> > > >
> > > >         warn("rc_map2id: can't find tty %s in map database",
> > > > ttyname);
> > > >
> > > >         return 0;
> > > > }
> > > >
> > > > Есть любители кодить на язычке Си всякие прикладные вещи.
> > > > И там это ещё называется "качество кода" или как-то так.
> > >
> > > Это не качество кода, это несоответствие занимаемой должности. :-)
> >
> > Дело в том что в язычке Си нет стандартного и эффективного способа
> > конкатенации двух строк.
>
> Простейший "стандартный" варинат -- использовать snprintf:
>
> 	char dest[PATH_MAX];
> 	snprintf(dest, sizeof(dest), "%s%s", s1, s2);
>
> Тут недостаток в том, что резервируется место на стеке, которое заведомо
> многократно превышает то место, которое скорее всего потребутеся.  Это
> уже плохо.  PATH_MAX это кажется 4096, то есть это размер страницы
> памяти в ядре.  При входе в такую функцию ядро будет "раздвигать" стек,
> если он ещё недостаточно раздвинут, что, в общем, не дёшево.  Это же
> может "затриггить" своп!

А если ещё и рекурсия...

>
> Но, вместе с тем, полной гарантии от "обрезания" окончания строки нет,
> то есть места всё же может на хватить.
>
> Другой полустандартный вариант -- это asprintf.
>
> 	const char *str = NULL;
> 	if (asprintf(&str, "%s%s", s1, s2) > 0 && str) {
> 		...
> 	} else {
> 		/* обломалось */
> 	}
>
> asprintf внутренне вызывает malloc, а это тоже не самая дешёвая
> операция, которая к тому же приводит к фрагментации памяти (к
> глибсишному маллоку почему-то много претензий на эту тему).

Особенно к glibc-2.5 (кстати, эта версия ещё где-то в дистрибутивах 
используется, кроме наших?)

___
Led.


Подробная информация о списке рассылки Devel