Вычитание 2 указателей, возвращаемых malloc с нулевым размером - PullRequest
0 голосов
/ 22 апреля 2019

У меня есть структура данных очереди, определенная как (NULL проверки опущены для простоты)

struct ml_queue {
    void *buf;
    void *next_elemnt;
    size_t size;
}

struct ml_queue *ml_queue_alloc(size_t size){
    struct ml_queue *mq_ptr = malloc(sizeof(*mq_ptr));
    void *buf = malloc(size);
    ml_queue->buf = buf;
    ml_queue->size = size;
    ml_queue->next_element = buf;
    return ml_queue;
}

bool ml_queue_is_empty(struct ml_queue *queue){
    char *buf = queue->buf;
    char *next = queue->next;
    char *limit = buf + queue->size;
    return limit - buf > 0; //Here is the question
}

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

struct ml_queue *q = ml_queue_alloc(0);
bool is_empty = ml_queue_is_empty(q); //UB?

Как известно malloc возвращает объект размера, переданного в качестве параметра. Массивы не могут быть пустыми по определению.

Но можем ли мы считать, что malloc(0) выделяет массив объекта нулевого размера с 1 элементом? Объект определен в разделе 3.15 стандарта как

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

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

1 Ответ

3 голосов
/ 22 апреля 2019

Что malloc(0) возвращает - это поведение, определяемое реализацией.

Согласно стандартному разделу C11 (n1570) в Поведение, определяемое реализацией :

Функции calloc, malloc и realloc возвращают нулевой указатель или указатель на выделенный объект, когда запрошенный размер равен нулю (7.22.3).

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

...