LINUX.ORG.RU

Динамические строки Си

 


1

1

Всем привет. Только что залил в реп пробную либу для работы с динамическими строками. Очень прошу, посмотрите как она там) Интересно узнать мнение о качестве кода и качестве текущей имплементации. Ссылка: https://github.com/maksspace/dynamic-string



Последнее исправление: maksspaces (всего исправлений: 1)
Ответ на: Исправил) от maksspaces

За такие commit messages нужно убивать ржавой секирой.

Deleted
()

Для работы с динамическими строками есть asprintf и realloc/snprintf. Этот велосипед не решает ни одной проблемы, кроме очередной недешевой попытки прикинуться, что у тебя не сишка, а ЯВУ. Если начнешь на сишке писать целевой (омг) код, а не велосипедить тул-либы форфан, то поймешь, что реальных юз-кейсов у таких поделок 0%.

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

Употребляющим только легкие наркотики.

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

Шел 2015 год. Была написана еще одна библиотека строк для си.

Любой новый ЯП — это всего лишь еще одна попытка устранить недостатки строк в си.

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

плюсую этого анонима, dystr_new — ужас

ТС, переписывай все, а лучше покажи Торвальдсу, он тебя научит больше никогда не писать код

unt1tled ★★★★
()
#define __dystr_capacity_inc(strptr,inc_size)

Во-первых, так ли нужно было делать эти штуки макросами? Почему не функции?

Во-вторых, зачем заставлять пользователя твоей библиотеки инклудить эти макросы? Спряч их куда подальше.

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

В-третьих не называй макросы на «__»

anonymous
()

Главное под гнётом гнева не выходи на эмоции и продолжай развивать, взвешивая все (включая щелочные замечания) и учитывай их если они разумны. Удачи ::)

Dron ★★★★★
()

Интересно узнать мнение о качестве кода и качестве текущей имплементации.

API не нравится. В функцию создания строки нельзя сразу передать начальное значение. К строке нельзя добавить данные из буфера, не заканчивающегося на \0. Названия добавляющих функций вводят в заблуждение. Без взгляда на прототипы функций сложно понять, чем отличаются _str от _chrs и _ch. Группа функций isequal бессмысленна, так как есть прямой доступ к полю data в dystring_t. Нет документации на способ хранения данных в data (есть \0 терминатор или нет). _length не имеет смысла, поле len в dystring_t доступно. _isempty не имеет смысла, можно просто взять длину и сравнить с нулём. _clear не имеет смысла, можно просто занулить длину. _print_to просто не нужно, если есть доступ к data и fprintf(). Библиотеке для работы со строками вообще нет смысла уметь их печатать куда-либо.

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

А, да. Чтобы библиотеку стоило лицензировать под GPL, она должна быть нереально хороша. Я понимаю, тебя жаба душит, но такой код никому не нужен, его никто тырить не будет.

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

Создавать хорошие библиотеки сложнее, чем писать программы, их использующие.

this. он бы еще с фреймворка начал

unt1tled ★★★★
()
Ответ на: комментарий от i-rinat

Библиотеке для работы со строками вообще нет смысла уметь их печатать куда-либо

Если строка спрятана внутри (что стоило бы сделать в этом случае), то функция для вывода в файл оправдана.

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

dyn_string.h

struct dyn_string;

dyn_string.c

struct dyn_string {
    ....;
};

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

Кстати, двойное подчёркивание в начале идентификатора (__*) зарезервировано реализацией, то есть обычный программист им пользоваться не должен.

Deleted
()

Я так понимаю, ты учишься программировать, и это одна из первых твоих программ. В данном случае всё хорошо, ты молодец.

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

ну вроде того) я хочу практики, большой практики.

maksspaces
() автор топика

А ничего страшного, если в dystr_substr_chrs from окажется больше, чем to?

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

Спасибо) Я сначала вообще об этом не подумал) Получается у меня никогда не освобождается место под данные? А только первые 16 байт где сама структура лежит?)

maksspaces
() автор топика
Ответ на: комментарий от maksspaces

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

Ты делаешь примерно так:

void add_str(dyn_str *str, ....) 
{
    dyn_str *tmp = realloc(str, ...);
    ..........
    str = tmp;
}

Что неверно.

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

А почему не работает?

вот здесь тоже я в начале блока храню структуру, но realloc ошибку не выдает, хотя делается тоже самое что и выше:

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    int len;
    int cap;
    char *data;
} str_t;

int main(int argc, const char * argv[])
{
    str_t *n = malloc(sizeof(str_t) + 32);
    
    if(n != NULL)
        n->data = (char*)(n + sizeof(str_t));
    else
        printf("n == NULL\n");

    n->cap = 32;
    n->len = 0;
    
    
    str_t * tmp = realloc(n, sizeof(str_t) + 4096);
    n = tmp;
    free(n);
    
    return 0;
}

maksspaces
() автор топика
Ответ на: комментарий от maksspaces

тебе тут уже несколько раз намекнули, что

void del( str* s ) 
{
    s = NULL;
}

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

void setnull( void *p )
{
    p = NULL;
}

int main( )
{

    int r = 0;
    int *ip = &r;
    printf( "%x\n", ip );
    setnull( ip );
    printf( "%x\n", ip );
    return 0;
}

С реаллоком такая ж фигня. Ты реалочишь локальный указатель, а в случае, когда realloc у тебя меняет ЗНАЧЕНИЕ указателя, ты это значение теряешь внутри функции. В результате указатель, который ты скармливаешь в свою функцию становится невалидным, сохраняя свое старое значение.

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

Все дошло. Те в принципе нафиг никому не нужно занулять указатель при освобождении? Это должен делать пользовательский код а не код библиотеки так? Если передавать адрес указателя то все работает пеперь

#include <stdio.h>
#include <stdlib.h>

void setnull( void ** p_addr )
{
    *p_addr = NULL;
}

int main( )
{
    
    int r = 0;
    int *ip = &r;
    
    printf( "%x\n", ip );
    setnull( &ip );
    printf( "%x\n", ip );
    return 0;
}
maksspaces
() автор топика
Ответ на: комментарий от maksspaces

Вот поэтому такие вещи обычно делают с 2 этапами выделения памяти. 1: сама структура 2: дынные, которые она содержит. Чтоб внутренние указатели не зависели от внешнего, да да.

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

Внимательно не смотрел, но в функции сравнения строк можно обойтись без медленного strlen.

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

test.c же)

//Автор указывал выше, что тренируется, не надо придираться, а за README.md особая хвала.

backbone ★★★★★
()
Последнее исправление: backbone (всего исправлений: 1)
Ответ на: комментарий от i-rinat

Я пишу ее в принципе больше для практики) а вообще я хочу написать интерпритатор языка Scheme, c небольшими изменениями. Пробовал, задолбался писать длинные имена функций.

Мне не нравится API который сейчас. Вот я думаю на чем остановиться: https://raw.githubusercontent.com/maksspace/dynamic-string/master/dstring.md

maksspaces
() автор топика
Ответ на: комментарий от maksspaces

а вообще я хочу написать интерпритатор языка Scheme, c небольшими изменениями.

и библиотека соответственно для разбора исходников scheme

maksspaces
() автор топика

До аудита кода выясним кое-какие вопросы.

Если не дооформил правильно копирайты и не указал лицензию, то это выглядит как разновидность порции собственнического кода.

Наверное автор хотел сделать его открытым все-же.

anonymous
()

Замечание по api. Часто нужны варианты new и append, принимающие параметром не char*, а динамическую строку.

German_1984 ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.