Я пока не могу – мне тут valgrind какую-то дичь верещит.

Есть такой вот код:

struct entry_s {

    void (*handler) (void);

    struct entry_s *next;

};

typedef entry_s entry_t;


typedef struct {

    entry_t *first;
    entry_t *last;

} entries_t;


// сюда они добавляются в начале рантайма
static entries_t entries = { NULL, NULL };


// где-то ниже по коду дела

entry_t *entry = entries.first;

while (entry) {

    entry->handler();

    entry = entry->next; // valgrind: Invalid read of size 8
}

Вот скажи мне, как неойтишник, какого хуя ему не нравится?

  • deep-purpleOP
    link
    fedilink
    arrow-up
    0
    ·
    3 years ago

    мне всё равно не нравится

    Ты бы мысль то развернул. Вдруг дельные аргументы какие есть.

    • ThePlayerZero
      link
      fedilink
      arrow-up
      0
      ·
      3 years ago

      А, ну и last нужен и для односвязного, если в него подразумевается аппенд без цикла до последнего элемента.

      Не знаю, мне всё равно не нравится… Ну ладно, если у тебя на самом деле двусвязный, то этот вопрос исчерпан

      Ты бы мысль то развернул. Вдруг дельные аргументы какие есть.

      1. (Теоретико-эстетствующий) Односвязный список – это каноничная структура данных. Да, в C он реализуется на указателях и позволяет хак в виде быстрого аппенда в конец. В том же Haskell ты так принципиально не сделаешь, поскольку там нет ни указателей, ни ссылок.

      Тут нарушается некая “регулярность” между имплементациями, я не могу точный термин подобрать, но что-то здесь не то :)

      1. (Консистентность API) Забыли про другие языки. Что такое односвязный список? Это стек, стопка. Ты можешь положить только наверх стопки, или взять сверху – всё.

      Потом ты приходишь и говоришь – а мой односвязный список лучше, там можно ещё подложить “горшок” (Вы не скажете, где здесь туалет? Нашел время! Спасибо) под самый низ. Юзеры довольны, больше функционала – ведь лучше… Или нет?

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

      Итак, получился односвязный список с тремя методами: push, pop, (сверху), append (под низ), но без pop_back. И по-прежнему с доступом за O(N) ко всем элементами, кроме верхних и самого последнего. Ну хз. Если и существует практический кейс, где нужно именно такое API, то мне он в голову не пришёл. Вот.

      • deep-purpleOP
        link
        fedilink
        arrow-up
        0
        ·
        edit-2
        3 years ago

        Что такое односвязный список? Это стек, стопка. Ты можешь положить только наверх стопки, или взять сверху – всё.

        Если и существует практический кейс, где нужно именно такое API, то мне он в голову не пришёл

        То, о чём говоришь ты – FILO/LIFO.

        То, что нужно мне (не XOYO):

        1. Быстрая вставка в конец, поэтому в “холдере” entries есть поле last.

        2. Быстрое вынимание из любого места, поэтому в entry есть поля prev и next.

        3. Пробежка в цикле по тем элементам, которые там есть на момент пробежки.

        Тщем – это подписчики на событие.

        • ThePlayerZero
          link
          fedilink
          arrow-up
          0
          ·
          3 years ago

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

          Что с багом то? Минимал так и не удалось построить? Ты с санитайзерами пробовал собирать и запускать свой (весь) код?

          • deep-purpleOP
            link
            fedilink
            arrow-up
            0
            ·
            3 years ago

            Баг дал понять, что внутри entry-хендлера какой-то гандон портит указатель на сам entry. Ну и по классике, оказалось, что этот гандон – я. Исправлено.

      • TheAnonymous
        link
        fedilink
        arrow-up
        0
        ·
        3 years ago

        «где нужно именно такое API» Очередь (FIFO)

        • ThePlayerZero
          link
          fedilink
          arrow-up
          0
          ·
          3 years ago

          Итак, получился односвязный список с тремя методами: push, pop, (сверху), append (под низ), но без pop_back. И по-прежнему с доступом за O(N) ко всем элементами, кроме верхних и самого последнего. Ну хз. Если и существует практический кейс, где нужно именно такое API, то мне он в голову не пришёл.

          Очередь (FIFO)

          Для фифо push не нужен, достаточно append и pop в этой терминологии

          • TheAnonymous
            link
            fedilink
            arrow-up
            0
            ·
            3 years ago

            push не нужен, но голова и хвост нужны

            • ThePlayerZero
              link
              fedilink
              arrow-up
              0
              ·
              3 years ago

              Ну так добавление в хвост и удаление с головы это и есть два метода (функции), а не три

              • TheAnonymous
                link
                fedilink
                arrow-up
                0
                ·
                3 years ago

                А причем здесь функции, в ОП вообще нет функций Это к «А нафига тут поле last вообще, если с него нельзя пойти в обратном направлении? Список то односвязный» На односвязном списке с поддержкой вставки в конец можно сделать очередь