Существуют ли какие-либо фактические реализации, которые разрешают `char array[SIZE_MAX];` (или успешный эквивалент с использованием `malloc`)?

Стандарт C99 предполагает, что тип size_t достаточно велик для хранения размера любого объекта, поскольку он является результирующим типом оператора sizeof.

Оператор sizeof возвращает размер (в байтах) своего операнда, который может быть выражением или именем типа в скобках. ...

Значение результата... определяется реализацией, а его тип (целочисленный тип без знака) — size_t, определенный в (и других заголовках).

Поскольку SIZE_MAX (<limits.h>, если я правильно помню) определяется как наибольшее значение, которое может хранить size_t, из этого должно следовать, что самый большой объект будет иметь размер, равный SIZE_MAX. На самом деле это было бы полезно, но, увы, кажется, что мы просим довольно много, чтобы выделить хоть четверть этого размера.

  • Существуют ли какие-либо реализации, в которых вы можете фактически объявить (или иным образом выделить) объект размером SIZE_MAX?

Это, конечно, не совсем обычный случай... В C11 были введены необязательный тип rsize_t и соответствующий ему макрос RSIZE_MAX. Предполагается, что это ограничение времени выполнения, если любая стандартная функция C используется со значением больше RSIZE_MAX в качестве аргумента rsize_t. Кажется, это означает, что самый большой объект может быть RSIZE_MAX байт. Однако это, похоже, также не получило широкой поддержки!

  • Существуют ли какие-либо реализации, в которых существует RSIZE_MAX, и вы можете фактически объявить (или иным образом выделить) объект размером RSIZE_MAX?

person autistic    schedule 05.06.2015    source источник
comment
из этого должно следовать, что самый большой объект будет иметь размер, равный SIZE_MAX - это неверно. Это просто означает, что SIZE_MAX по крайней мере настолько велик, насколько может быть самый большой объект.   -  person Michael Burr    schedule 05.06.2015
comment
@MichaelBurr Когда я использовал действующее ключевое слово should, я имел в виду, что SIZE_MAX на самом деле не говорит нам ничего полезного об объектах, но не стесняйтесь игнорировать эту часть вопроса ... и, пожалуйста, убедитесь, что раздел комментариев оставлен доступным, чтобы запросить разъяснения, а не придираться к деталям, которые не делают фактический вопрос недействительным.   -  person autistic    schedule 05.06.2015
comment
Почему, вы ожидаете, что любые ответы расскажут вам что-нибудь (практически) полезное о размере объектов? Этот вопрос смехотворно теоретический.   -  person Karoly Horvath    schedule 05.06.2015
comment
Да, @KarolyHorvath, я ожидаю, что если будут какие-либо ответы, они будут называть фактические реализации, в которых я могу объявлять или иным образом распределять объекты размером до SIZE_MAXRSIZE_MAX) ... поскольку это ясно то, что мои вопросы задают.   -  person autistic    schedule 05.06.2015
comment
Я подозреваю, что C-реализация для 8086 могла бы быть намного проще, если бы она ограничивала SIZE_MAX до 64 КБ, поэтому любой объект мог всегда помещаться в один сегмент памяти.   -  person EOF    schedule 05.06.2015
comment
@EOF Я подозреваю, что все для 8086 могло бы быть намного проще, если бы тогда они поняли, что куча 20-битных адресных регистров вместо сегментов сэкономит десятилетия сегментной питы.   -  person user3125367    schedule 05.06.2015
comment
Мне любопытно, с какой идеей или проблемой вы столкнулись, прежде чем задать этот вопрос?   -  person user3125367    schedule 05.06.2015
comment
@user3125367 user3125367 Проблема увеличения коллекций с использованием realloc и определения того, когда выделение не удастся из-за огромного размера, чтобы сдаться в этот момент.   -  person autistic    schedule 08.06.2015
comment
@ user3125367: Вы когда-нибудь работали с 20-битными адресными регистрами? Большинство языков не очень хорошо поддерживают сегментацию, но сегменты с масштабируемыми адресами означают, что объекты размером до 64 КБ могут быть размещены на любой 16-байтовой границе, в то время как 20-битные адресные регистры усложняют работу с объектами, пересекающими границы 64 КБ. Объектно-ориентированная среда, такая как Java, но с 16-битными типами, может быть очень эффективной на x86, поскольку ссылки должны быть только 16-битными, а не 32-битными.   -  person supercat    schedule 25.06.2016
comment
@supercat Будьте осторожны, чтобы не поддаться туннельному видению, когда дело доходит до оптимизации; возможно, они не выполнили такую ​​оптимизацию, потому что это может вывести другие возможности за рамки практичности, или есть более важные проблемы, которые необходимо учитывать (например, сборщик мусора Java). Что еще более важно, Java имеет 16-битный тип; вы рассматривали short? Также есть char, который IIRC является типом символов Unicode, но не цитируйте меня по этому поводу.   -  person autistic    schedule 05.07.2016
comment
@Seb: Java поддерживает упакованные массивы short, byte и char, но не поддерживает ничего, что не кратно 32 битам. Переменная типа short представлена ​​в среде выполнения точно так же, как переменная типа int; единственное отличие с точки зрения языка состоит в том, что переменные типа short могут быть записаны в short[] без приведения, а сохранение значения в переменной типа short приведет к расширению по знаку нижней половины в верхнюю половину до того, как она будет записана.   -  person supercat    schedule 05.07.2016
comment
@supercat Из моего вопроса OP вы можете понять, что я ожидаю, что ваш источник информации будет заслуживающим доверия. Пожалуйста, дайте мне ссылку на раздел JLS, который указывает, что short имеет такое же представление. Пока вы читаете спецификацию, есть ли какие-либо доказательства того, что Object должно быть внутренне представлено с использованием числа, кратного 32 битам?   -  person autistic    schedule 06.07.2016
comment
@Seb: существуют инструкции для загрузки и сохранения из локальных значений типов int, long, float, double и ссылок, а также для усечения более длинных типов до более коротких и преобразования int или float в long или double соответственно. Использование putfield или putstatic требует, чтобы значение, сохраняемое в поле типа int, boolean, byte, char или short, должно было иметь тип int, в то время как значения long, float или double могут храниться только в полях соответствующих типов. .   -  person supercat    schedule 06.07.2016


Ответы (2)


Я думаю, что все реализации C позволят вам объявить объект такого размера. ОС может отказаться загружать исполняемый файл из-за нехватки памяти.

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

Только подумайте: если size_t — это тип, равный размеру машинного слова (32 бита, 64 бита), то самая старшая адресуемая ячейка памяти (байт) равна 2^32 (или 2^64). Учитывая, что существуют более низкие векторы прерывания памяти, BIOS и ОС, не говоря уже о коде и данных вашей программы, такого объема памяти никогда не бывает.

person Paul Ogilvie    schedule 05.06.2015
comment
На самом деле компоновщик может пожаловаться, если вы объявите огромный статический или глобальный объект. - person Basile Starynkevitch; 05.06.2015
comment
Термин реализация относится не только к компилятору и стандартной библиотеке; это также относится к среде выполнения. - person autistic; 05.06.2015

О, теперь я вижу проблему. Предполагая коэффициент realloc ~ 1,5, есть два целочисленных ограничения. Во-первых, это SIZE_MAX/3, потому что выше этого size*3/2 будет переполнено. Но при этом большие младшие биты несущественны, и мы можем изменить порядок оператора на size/2*3, чтобы он все равно увеличивался примерно на 1,5 (что накладывает второй предел SIZE_MAX/3*2). Наконец, прибегайте к SIZE_MAX.

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

int
grow(char **data_p, size_t *size_p, size_t min)
{
    size_t size = *size_p;

    while (size < min)
        size = (size <= SIZE_MAX / 3     ? size * 3 / 2 :
                size <= SIZE_MAX / 3 * 2 ? size / 2 * 3 : SIZE_MAX);

    if (size != *size_p) {
        size_t ext = size - min;
        char *data;

        for (;; ext /= 2)
            if ((data = realloc(*data_p, size + ext)) || ext == 0)
               break;

        if (data == NULL) return -1; // ENOMEM

        *data_p = data;
        *size_p = size + ext;
    }
    return 0;
}

И никаких ограничений, зависящих от ОС или установленных вручную!

Как видите, первоначальный вопрос является следствием [вероятно] несовершенной реализации, которая не учитывает крайние случаи с уважением. Неважно, существуют или не существуют сейчас какие-либо сомнительные системы — любой алгоритм, который должен работать вблизи целочисленных пределов, должен надлежащим образом заботиться о них.

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

person user3125367    schedule 08.06.2015
comment
Это все прекрасно и денди, но я не уверен, как он даже пытается ответить на вопрос. Это скорее попытка обратиться к не относящемуся к делу комментарию (который вы подсказали). Пожалуйста, не делай этого. - person autistic; 08.06.2015
comment
Ваше намерение, похоже, не решает проблему правильно, гарантируя отсутствие успешной реализации, которая может соответствовать крайним случаям (и это оставляет вопрос в широко бесполезном состоянии). Я оставляю это для будущих посетителей, чтобы их не путали с недопустимыми подходами. Для вашего OP: сегодня нет систем, которые разделяют код и данные, поэтому данные будут SIZE_MAX, поэтому НЕТ. Но, пожалуйста, не соглашайтесь ни на что меньшее, кроме как на самое портативное и стандартное решение. - person user3125367; 09.06.2015
comment
Пожалуйста, не пишите ответы, основанные на предположениях. Мое намерение состоит в том, чтобы определить, существует ли такая реализация, чисто из любопытства, а не гарантировать, что успешной реализации не будет. Можете ли вы доказать, что ваш код соответствует всем крайним случаям? Возможно, если случайно существует такая система (например, SIZE_MAX определена как небольшая степень двойки минус единица, например 65535), как ваш код будет выделять максимально возможный объект? Есть ли вероятность того, что ваш начальный цикл может иметь ошибочные крайние случаи (думаю, очень маленькие значения для size), что приводит к тому, что он становится бесконечным? - person autistic; 09.06.2015
comment
Хотя в данном случае функциональность явно превосходит переносимость и соответствие стандартам (мой код в равной степени переносим и соответствует стандартам, но на самом деле работает правильно), насколько это переносимо? В реализации, которая не содержит нет realloc, это, очевидно, не сработает... Итак, вы говорите мне выбрать наиболее переносимое, совместимое со стандартами решение... что, очевидно, вам не подходит. код, который имеет глючные пограничные случаи (возможно, даже не тестировался) и даже не будет компилироваться или работать в самых минимальных реализациях. - person autistic; 09.06.2015
comment
В соответствии с этой логикой, возможно, было бы лучше переписать ваш ответ, не полагаясь на realloc. - person autistic; 09.06.2015
comment
Вы правильно заметили, что начальный размер 0 будет зацикливаться навсегда. Намерение состояло в том, чтобы показать поведение только в верхнем пределе, а не в полностью проверенной и протестированной версии, что было бы излишним в формате SO. Поскольку realloc является ISO C, я не вижу никаких проблем с его использованием в решении, совместимом со стандартами. Теперь, когда ясно, что вопрос был просто любопытством без какой-либо сопутствующей практики, я помечаю этот ответ как публично удаляемый. - person user3125367; 09.06.2015
comment
Это также зацикливалось бы бесконечно, если бы начальный размер был равен 1. В любом другом случае стандартные документы C две формы среды. <stdlib.h> (и, как следствие, realloc) должен существовать для размещенных сред, но не для автономных сред... поэтому ваш пример переносим для размещенных сред. Имейте в виду, что недавно я обнаружил некоторые тонкие несоответствия между стандартными библиотеками и сегодняшними реализациями, которые технически помещают их в автономные с наиболее размещенным соответствием. Этот вопрос может быть одним из примеров. - person autistic; 09.06.2015
comment
Я решил опубликовать написанную мной функцию (несовершенная реализация, которая не учитывает пограничные случаи) вместе с некоторыми другими функции, работающие с массивами. Пожалуйста, сообщите, должен ли мой алгоритм, который должен работать вблизи пределов целочисленных значений, должным образом заботиться о них, о высший тот, кто может читать мысли, напишите потрясающий код с ошибками, который не работает для меньших целых чисел. ограничения и делать выводы о фрагментах кода, которые вы даже никогда не видели... PS Я немного запутал, чтобы вас расстроить ;) - person autistic; 06.07.2016
comment
К сожалению, я не могу проверить это, потому что я слишком занят, но мой отдел контроля качества ответил довольно хорошо, за исключением нескольких вещей по этому поводу. Это был долгий путь, и теперь ты в порядке. Спасибо, что помните эту тему! - person user3125367; 06.07.2016
comment
Этот вопрос возник при написании этого кода... Действительно, код (особенно push_back) немного старше. Кажется, ты намекаешь, что я многому научился за последний год, но это не так. Что касается C, я изучаю его уже более десяти лет ... Я думаю, что мое обучение могло резко застопориться пять лет назад или около того по какой-то причине ... Либо у меня заканчиваются вещи, о которых можно было бы узнать. или я умственно отсталый, который просто не может учиться. Я полагаю, что вы уже сформировали свое мнение. Есть ли у него какое-то оправдание? - person autistic; 07.08.2016
comment
... сегодня нет систем, разделяющих код и данные,... Вы уверены в этом? Рассматривали ли вы какие-либо микроконтроллеры с кодом на флэш-памяти только для чтения и данными на DRAM? Возможно, в какой бы развивающейся стране вы ни были, вы не можете себе их позволить (или учебники, необходимые для их изучения). Хотите пожертвование? - person autistic; 12.08.2016