Вы сказали, что sizeof (size_t) == 2
(это для MS-DOS 6.22).
Это означает, что максимальное значение size_t
равно 65535
.
unsigned long buffSize = 65536; /* 64 KB */
Проблем пока нет. unsigned long
должен быть не менее 32 бит (и 32 бит в вашей системе), поэтому он может легко удерживать значение 65536
.
char *block;
block = calloc(1, buffSize);
Оба аргументы calloc
имеют тип size_t
. Любой аргумент, который не относится к типу size_t
, неявно преобразован. Преобразование 65536
в size_t
дает 0
. Таким образом, вы запрашиваете выделение 0 байтов. Поведение такого распределения определяется реализацией; он может возвращать нулевой указатель или может возвращать уникальный ненулевой указатель, аналогичный malloc(1)
, за исключением того, что вы не можете разыменовать его. Ваша реализация, по-видимому, делает первое.
calloc
принимает два аргумента, оба типа size_t
. Их значения не просто умножаются, чтобы получить результат типа size_t
. Вместо этого calloc
должен либо успешно присвоить количество байтов, заданных , либо, не сможет этого сделать и вернуть нулевой указатель.
В принципе, вы можете написать:
block = calloc(64, 1024);
или что-то подобное. Если он преуспеет, он выделит объект размером 65536 байтов.
Но так как size_t
всего 16 бит, это почти наверняка означает, что реализация не может создавать объекты размером не более 65535 байт. Нет фактического запрета на создание объектов размером больше SIZE_MAX
байт, но любая реализация, которая в состоянии сделать это, почти наверняка сделает его size_t
больше, чтобы он мог представлять размер любого объекта.
(SIZE_MAX
максимальное значение типа size_t
. Это макрос, определенный в <stdint.h>
, который был введен в стандарте C99. Ваша реализация, вероятно, не поддерживает <stdint.h>
. Выражение ((size_t)-1)
эквивалентно.)
Вам, вероятно, не повезло, если вы не используете другую реализацию (что может означать использование одного и того же компилятора с разными опциями).
Возможно, вы можете переконфигурировать свою программу, чтобы использовать, например, два 32768-байтовых объекта, а не один объект размером 65536 байтов (хотя это может и не поддерживаться).
Системы MS-DOS поддерживают (поддерживаются?) Несколько моделей памяти, некоторые из которых могут позволить вам делать то, что вы хотите. Я не знаю подробностей. Для получения дополнительной информации обратитесь к документации вашего компилятора.
Это скорее всего, OS/buildtree конкретный ответ, так что ... ОС построить дерево? – IdeaHat
Работает ли malloc и memset? – mch
Сумасшедшая идея, 'calloc (buffSize, 1)'. Также попробуйте 'unsigned long buffSize = 65536L; '. Я понятия не имею, какие ограничения на вашей платформе. – Persixty