«Маркировка» указателей в C с помощью «атрибутов»

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

Теперь у меня вопрос, есть ли способ «пометить» некоторые регионы как «доступные для размещения», «доступные для записи» и «зарезервированные» в этом буфере, как в Kernel Development.

Например, у нас есть буфер с 6 элементами, как я могу пометить элементы 2-5 как «зарезервированные»?

   [0][1][2][3][4][5]

Возможно ли это с помощью флагов, битовой манипуляции или чего-то еще? Или я могу отметить указатель?

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

Fiddling Bits 17.08.2018 16:15

Отложите какую-то структуру данных для хранения записей. Забудьте пока о битовых манипуляциях.

Eugene Sh. 17.08.2018 16:17

Массив 'struct' (или связанный список), который включает флаг в каждом экземпляре, который вы можете установить, чтобы указать, разрешено ли выделение, или нет.

ryyker 17.08.2018 16:21

Вероятно, было бы проще реализовать пул блоков, чем пул байтов.

Fiddling Bits 17.08.2018 16:21

Разве связанные списки не сильно повлияли бы на производительность?

Lazcano 17.08.2018 16:23

Когда вы говорите о производительности, вы должны сравнивать с что-то. Итак, «огромное влияние» по сравнению с чем?

Eugene Sh. 17.08.2018 16:25

@Lazcano В своем вопросе вы не упомянули никаких ограничений или требований. Не сообщая нам, вы не получите правильных ответов.

AndersK 17.08.2018 16:25

Большое спасибо за вашу помощь! :) @EugeneSh. - по сравнению с malloc. Я буду следить за AndersK. совет!

Lazcano 17.08.2018 16:29

Если вы хотите конкурировать со стандартным malloc, вы можете сначала взглянуть на его реализацию. Что, кстати, может сильно различаться.

Eugene Sh. 17.08.2018 16:29

Вызов malloc по сравнению, скажем, со статически определенной памятью в стеке, снижает производительность. Истинно, содержится ли указатель в массиве структур или в связанном списке.

ryyker 17.08.2018 16:30

Реализации AFAIK FreeBSD являются одними из лучших, если не лучшими.

Lazcano 17.08.2018 16:39

@Lazcano - просто к сведению, когда вы хотите отправить текст кому-то конкретно, в поле для комментариев начинайте с символа @, за которым сразу следует псевдоним пользователя. Например, @ryyker вызовет появление связанного уведомления в верхней части страницы SO, уведомляющего меня о том, что кто-то оставил комментарий, позволяя мне щелкнуть это уведомление и просмотреть комментарий. :)

ryyker 17.08.2018 17:04

@ryyker Спасибо :)

Lazcano 17.08.2018 17:23
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
13
148
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете использовать что-то столь же простое, как массив struct (или linked list), который включает флаг в каждом экземпляре, который вы можете установить, чтобы указать, разрешено ли выделение, или нет. Например, используя флаг и неоднозначную типизацию (void *):

typedef struct {
    BOOL alloc; //set TRUE to allow or FALSE to disallow further allocation
    void *space;
    //other members
}BUF;

Создайте массив BUF и установите для члена alloc значение TRUE или FALSE, чтобы сделать экземпляр более недоступным для изменения его памяти. Конечно, это произойдет после того, как начальная память была выделена во время инициализации.

Или другая возможность использования типов enum в сочетании с union:

typedef enum {
    _INT,
    _UINT,
    _CHAR,
    _UCHAR,
    ... //other types
}TYPE;

typedef struct {
    BOOL alloc; //set to allow or disallow further allocation
    TYPE type;  //flag to track type being used in instance
    union {
        char *cMem;
        unsigned char *ucMem;
        int *iMem;
        unsigned int *uiMem;
        ... // other members

    char *space;
}BUF;

Почему char *? Может void *?

Fiddling Bits 17.08.2018 16:27

Лучше подойдет void *, так как он подходит для большинства случаев. У меня слишком мало представителей для голосования, извините, но я ценю ваш ответ!

Lazcano 17.08.2018 16:31

@Lazcano - без проблем. Кстати, объединение типов также может быть включено в структуру, представляющую необходимый type. (Но редактирование показывает предложение Fiddling Bits)

ryyker 17.08.2018 16:33

Вот так. Лично я предпочитаю void* с явным приведением.

Lazcano 17.08.2018 16:37

Преобразуйте количество буферов в битовый массив беззнакового int и используйте индекс памяти, чтобы пометить его. Например: unsigned int allocatable [((x) +31) >> 5]; аналогично для записываемых и зарезервированных.

Почему ((x) +31)>>5? Вы можете объяснить?

Fiddling Bits 17.08.2018 16:37

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

Lazcano 17.08.2018 16:44

Предположим, что X - максимальное количество буферов, например: 120, тогда выделяемый [(120 + 31) >> 5) будет доступен для размещения [30]. Если вы выделяете память для индекса 4, а затем устанавливаете allocatable [index >> 5] | = (1 << (index & 0x31), этот способ можно использовать для установки и сброса при необходимости. (1 или 0)

Sai Karthik K 17.08.2018 16:48

Другие вопросы по теме