|
|
ru.unix.bsd- RU.UNIX.BSD ------------------------------------------------------------------ From : Valentin Nechayev 2:5020/400 29 Feb 2004 10:36:17 To : eugen@grosbein.pp.ru Subject : Re: Sendmail+qpopper -------------------------------------------------------------------------------- >>> Eugene Grosbein wrote: VN>> Hо это не значит, что ты имеешь право так писать. Присвоил указателю VN>> на неконстантное строковую константу - сам виноват, думать надо было VN>> и понимать, что пишешь не на ЯВУ, а на слабопереносимом ассемблере VN>> фоннеймановских машин с двоичной иерархией размерностей. EG> Да я знаю, я и говорю про то, что так писать нельзя, поэтому strcpy. Hет. Поэтому должно быть хотя бы strlcpy, а не функция, которая предполагает неограниченный буфер, которого гарантированно хватит. А лучше даже не strlcpy или любая другая функция для С-строк, а что-то более нормальное. C-строки обязаны быть в единственном месте - интерфейс с libc и другими аналогичными системными средствами. В остальных местах от них по возможности надо уходить. EG>>> Постоянно не копирую. Изредка. VN>> Что, в твоём коде сплошной buffer sharing & copy-on-write? EG> Про buffer sharing не понял. COW дает OS, главное ей не мешать. OS не даст никакого COW, когда ты делаешь str*cpy(). Про buffer sharing я имел в виду подход такого вида: struct sbuf { char* data; size_t size, length; unsigned usecnt; }; struct string { struct sbuf* buffer; }; struct string* string_copy( struct string* src ) { /* Просто увеличиваем счётчик ссылок. Когда потребуется изменить, * будет сделана копия */ struct string* t = calloc( 1, sizeof( *t ) ); if( t ) { ++src->buffer->usecnt; t->buffer = src->buffer; } return t; } int string_setsz( struct string* s, const char* txt ) { size_t l = strlen( txt ); struct sbuf* b = s->buffer; if( b->usecnt == 1 ) { /* Буфер наш личный, делаем что хотим */ if( sbuf_expand( b, l+1 ) < 0 ) return -1; } else { /* Сделать собственный буфер и скопировать в него */ assert( b->usecnt > 1 ); --b->usecnt; /* отсоединились */ s->buffer = 0; if( !( b = s->buffer = sbuf_new( l+1 ) ) ) return -1; } memmove( b->data, txt, l+1 ); b->len = l; return 0; } думаю, идея по этим кусочкам понятна. Библиотек, построенных по такому принципу, достаточно много, и оперирование со строками они делают значительно эффективнее, чем всякие str*cpy (которые кэшу процессора постоянно делают полный thrashing). VN>> Hет. С-строки - это когда принцип у них такой, что терминируются нулями VN>> и каждый раз надо считать нули. А если кто-то дописывает ((char)0) после VN>> конца буфера - это не более чем метод совместимости с интерфейсом POSIX. EG> Просто неохота libc дублировать. Оно работает, оно вылизано, EG> главное не слишком часто туда лазить. От того, что оно вылизано, оно нормальным API не становится. Так себе, подложка для минимального взаимодействия с ядром. -netch- --- ifmail v.2.15dev5.3 * Origin: Dark side of coredump (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.unix.bsd/7368f6fd39ce.html, оценка из 5, голосов 10
|