Кто-нибудь реализовал замену для string.h, используя структуру для хранения строки и длины? - PullRequest
3 голосов
/ 13 июня 2011

В стандартной библиотеке C строки реализованы с использованием массива символов, оканчивающегося нулевым символом: '\ 0'. Такие строки ASCIZ приводят к неэффективности, потому что каждый раз, когда нам нужно знать длину строки, нам нужно перебирать ее, ища '\ 0'.

Способ обойти это - сохранить длину строки при ее создании, например, используя структуру следующим образом:

typedef struct cstring_ {
    size_t nchars;
    char chars[0];
} cstring;

Кто-нибудь создал разделяемую библиотеку, реализующую функции string.h, но использующую структуру вместо char * для передачи строк?

Если нет, есть ли конкретная причина, по которой это было бы плохой идеей?

Ответы [ 7 ]

5 голосов
/ 13 июня 2011

Таких, наверное, десятки. Взгляните, например, на Glib GString .

3 голосов
/ 13 июня 2011

Кто-нибудь создал общую библиотеку, реализующую функции string.h, но использующую структуру вместо char * для передачи строк?

Я сделал.

11 лет назад, когда я учился C: я переопределил всебиблиотека, гарантируя, что перераспределения использовались всякий раз, когда в строке требовалось больше места.

Но тогда это было для целей обучения (так как тогда я перешел на C ++ и теперь использую std :: string).

есть ли конкретная причина, по которой это было бы плохой идеей?

Я думаю, это может быть хорошей идеей попробовать сами: таким образом, используя правильный API,Вы можете запомнить вдоль строки как ее длину, так и размер буфера, возможно, даже счетчик ссылок, если вы хотите попробовать поиграть с концепциями копирования при записи.Ваша строка будет более сложной, но в некоторых случаях более эффективной, чем стандартная.И это хороший опыт обучения.

Но для производственного кода, как всегда, либо вы очень опытный человек, либо вы должны попытаться найти библиотеку, которая сделает это лучше, чем вы.

Я знаю некоторые готовые к реализации реализации, использующие эту альтернативную строку.

Mat уже упоминал GString GLib.

Если вы программируете для Windows, Microsoft BSTR (и его оболочка C ++ bstr_t ) могут решить вашу проблему: их можно прочитать как строку const char *, и они используют SysAllocString и его дочерние функции, SysFreeString и т. Д.

Вы можете использовать их для производственного кода или в учебных целях, учиться у них.

1 голос
/ 13 июня 2011

Да, есть множество библиотек, которые делают это, включая Glib , BString , VStr и другие. Проблема в том, что они обычно довольно неудобны в использовании или, по крайней мере, требуют изучения нестандартных API для обработки строк. (C ++ std::string будет примером правильной обработки строк, но это зависит от многих возможностей C ++.)

Если вы опасаетесь стоимости strlen, вам следует вычислить длину строки «вручную», выполняя над ними операции, и выполнять большинство операций с memcpy и прямым доступом к символам. Это полезно только в крутых петлях.

1 голос
/ 13 июня 2011

Из C FAQ

Несмотря на свою популярность, эта техника также несколько печально известна: Деннис Ритчи назвал ее "неоправданной болтовней с реализацией C", иофициальное толкование показало, что оно не строго соответствует стандарту C , хотя, похоже, оно работает при всех известных реализациях.(Компиляторы, которые тщательно проверяют границы массивов, могут выдавать предупреждения.)

Также я думаю, что это должно быть char chars[1];.

0 голосов
/ 13 июня 2011

Не думаю, что это плохая идея, на самом деле реализация строки в c ++ такая же, как вы сказали. И есть также реализация, такая как gstring в glib. Это почти стандартная библиотека в мире Linux. Я думаю, что причина, по которой он не является стандартным c lib, заключается в том, что у c lang слишком длинная история, и большинство разработчиков и проектов используют для ориентации строки стиля c.

0 голосов
/ 13 июня 2011

Я нахожу, что всякий раз, когда мне нужна длина «строки», мне действительно нужно знать, является ли строка пустой или я достиг ее конца. В других случаях мне все равно нужно перебирать символы, чтобы я мог так же легко проверить NULL.

Итак, позвольте мне перефразировать ваш вопрос: есть ли конкретная причина, по которой вы думаете, что это лучше идея?

0 голосов
/ 13 июня 2011

Я реализовал нечто подобное в одном из моих проектов (однако вместо структуры я использовал класс). Это легко реализовать. Также рекомендуется хранить все, включая длину, в одной области памяти и представлять строку в виде указателя на начало самих данных строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...