Каков максимальный размер буферов, которые могут обрабатывать memcpy / memset и т. Д.? - PullRequest
7 голосов
/ 13 апреля 2009

Каков максимальный размер буферов memcpy и других функций, которые могут обрабатывать? Зависит ли эта реализация? Это ограничено размером (size_t), переданным в качестве аргумента?

Ответы [ 6 ]

11 голосов
/ 13 апреля 2009

Это полностью зависит от реализации.

Это зависит как от аппаратного обеспечения, так и от возраста компилятора. Для любого, имеющего достаточно современный компилятор (имеется в виду что-либо, основанное на стандарте начала 90-х или более поздних), аргумент size равен size_t. Разумно это может быть самый большой 16-битный без знака, самый большой 32-битный без знака или самый большой 64-битный без знака, в зависимости от модели памяти, к которой компилируется компилятор. В этом случае вам просто нужно выяснить, какой размер size_t в вашей реализации. Однако для очень старых компиляторов (то есть до ANSI-C и , возможно, для некоторых ранних версий ANSI C ) все ставки отключены.

Что касается стандартов, то, например, в Cygwin и Solaris 7 аргумент размера равен size_t. Глядя на имеющуюся у меня встроенную систему, аргумент size равен unsigned (имеется в виду 16-битный без знака). (Компилятор для этой встроенной системы был написан в 80-х годах.) Я нашел в Интернете ссылку на некий ANSI C , где параметром размера является int.

Возможно, вы захотите посмотреть эту статью на size_t, а также дополнительную статью о недоработке некоторых ранних версий GCC, где size_t ошибочно подписан.

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

1 голос
/ 14 апреля 2009

Функции обычно используют size_t для передачи размера в качестве параметра. Я говорю нормально, потому что fgets() использует параметр int, что, на мой взгляд, является недостатком в стандарте C.

size_t определяется как тип, который может содержать размер (в байтах) любого объекта, к которому вы можете получить доступ. Обычно это typedef, равный unsigned int или unsigned long.
Вот почему значения, возвращаемые оператором sizeof, имеют тип size_t.

Таким образом, 2 ** (sizeof(size_t) * CHAR_BIT) дает вам максимальный объем памяти, который может обработать ваша программа, но он, безусловно, не самый точный.
(CHAR_BIT определено в limits.h и дает количество битов, содержащихся в char).

0 голосов
/ 14 апреля 2009

Существует также проблема, связанная с тем, что size_t может представлять стихи, которые ваша платформа позволит на самом деле решать процессу.

Даже с виртуальной памятью на 64-битной платформе вы вряд ли сможете звонить memcpy() с размерами, превышающими несколько ТБ или около того, и даже тогда, это довольно горячая машина ... Трудно представить, на что была бы похожа машина, на которой можно было бы установить полностью покрытое 64-битное адресное пространство.

Не берите в голову встроенные системы, имеющие всего несколько КБ общей доступной для записи памяти, где не имеет смысла пытаться memcpy() получить больше информации, чем ОЗУ, независимо от определения size_t. Подумайте о том, что только что произошло со стеком, содержащим адрес возврата этого вызова, если вы это сделали?

Или системы, в которых виртуальное адресное пространство, видимое процессом, меньше установленной физической памяти. Это на самом деле имеет место, например, с процессом Win32, работающим на платформе Win64. (Впервые я столкнулся с этим во время совместного использования ОС TSX-11, работающей на PDP-11 с 4 МБ физической памяти и виртуальным адресом 64 КБ в каждом процессе. Тогда 4 МБ ОЗУ было много памяти, а IBM IBM не существует еще.)

0 голосов
/ 14 апреля 2009

Правильно, вы не можете скопировать области размером более 2 ^ (sizeof (size_t) * 8) байтов. Но это не о чем беспокоиться, потому что вы не можете выделить больше места, потому что malloc также принимает размер в качестве параметра size_t.

0 голосов
/ 14 апреля 2009

Зависит от реализации, но вы можете посмотреть в файле заголовка (.h), который вам нужно включить, прежде чем вы сможете использовать memcpy. Декларация скажет вам (ищите size_t или другое).

И затем вы спрашиваете, что такое size_t, ну, это часть, зависящая от реализации.

0 голосов
/ 14 апреля 2009

Они принимают аргумент size_t; так что это зависит от платформы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...