Распределение памяти компьютера для дублирующих входов - PullRequest
0 голосов
/ 24 февраля 2020

Я изучаю введение в CS (CS50, Гарвард), и мы изучаем объявление типа в C. Когда мы объявляем переменную и назначаем тип, компьютер выделяет определенное количество c бит / байт (1 байт для символа, 4 байта для int, 8 байтов для double и т.д. c ...).

Например, если мы объявляем строку «EMMA», мы используем 5 байтов, 1 для каждого символа «char» и еще 1 для нулевого байта \0.

Мне было интересно, почему 2 М выделяются отдельными байтами. Разве компьютер не может использовать символы или целые числа, занимающие в настоящее время место в памяти, и ссылаться на этот указанный слот c, когда он хочет использовать его повторно?

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

Редактировать: Исправлены некоторые биты в байтах - мой плохой

Ответы [ 3 ]

2 голосов
/ 24 февраля 2020

1 бит для char, 4 байта для int, 8 байтов для double и т. Д. c ...

Это общие значения, но они зависят от архитектуры (для этот ответ , в наши дни продаются даже 9-битные архитектуры на байты).

Разве компьютер не может использовать символы или целые числа, занимающие место в памяти в настоящее время? и ссылаетесь на этот указанный c слот, когда он хочет использовать его повторно?

Хотя эта идея, безусловно, осуществима в теории, на практике накладные расходы слишком велики для простых данных, таких как символы: один символ обычно это один байт.

Если бы мы настроили систему, в которой мы выделяем память для символьного значения и обращаемся к нему только из строки, строка будет состоять из серии элементов, которые будут используется для хранения того, какой символ должен быть там: в C это будет указатель (вы встретите их в какой-то момент в вашем курсе), и обычно он имеет длину 4 или 8 байтов (32 или 64 bi ц). Предполагая, что вы используете 32-битный указатель, вы будете использовать 24 байта памяти для хранения строки таким сложным способом, а не 5 байтов, используя более простой метод (чтобы расширить этот ответ , вам потребуется еще больше метаданные, чтобы иметь возможность корректно изменять строку во время выполнения вашей программы).

Однако ваша идея хранения фрагмента данных и обращения к нему несколько раз существует в нескольких случаях:

  • виртуальная память (вы столкнетесь с этим, если будете go к разработке ОС), где используется копирование при записи
  • языки более высокого уровня (например, C ++)
  • файловые системы, в которых реализована функция копирование при записи , например BTRFS
  • , некоторые системы резервного копирования (например, borg или rsyn c), которые дедуплицируют файлы / чанки, которые они хранят
  • Алгоритм сжатия в Facebook , где словарь малых общих кусочков данных используется для улучшения сотрудничества Коэффициент сжатия и скорость

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

1 голос
/ 24 февраля 2020

Например, если мы объявляем строку «EMMA», мы используем 5 бит

Я уверен, что вы говорите о 5 байтах вместо 5 бит.

Ну, мне было интересно, почему 2 М выделяются отдельными битами. Разве компьютер не может использовать символы или целые числа, занимающие в настоящее время место в памяти, и ссылаться на этот указанный c слот, когда он хочет использовать его повторно?

Указатель на «слот» обычно занимает 4 или 8 байтов. Поэтому нет смысла тратить 8 байтов, чтобы указать на объект, который занимает только один байт

Более того "EMMA" - это массив символов, который состоит из смежных байтов. Таким образом, все элементы массива имеют одинаковый тип и соответственно размер.

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

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

char *s = malloc( sizeof( "EMMA" ) );
strcpy( s, "EMMA" );

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

0 голосов
/ 24 февраля 2020

Предполагается, что компилятор не является кодом / программой, а является чем-то, что выполняет минимальные функции, и должен выполнять такие задачи, чтобы программистам было легко понимать и манипулировать ими, другими словами, он должен быть общим 1002 *.

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

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

с удовольствием уточнит, если потребуется. :)

...