Хобрук: Ваш путь к мастерству в программировании

Выравнивание памяти в массиве структур

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

struct { int x; char y; } arr[10];

Размер int на моей машине составляет 4 байта, а размер char - 1 байт. Я знаю, что структуры будут заполнены внутренне, т.е. каждый элемент массива будет иметь размер 8 байтов. Но я хочу знать, есть ли

1) Это связано с требованием выравнивания члена типа int в следующем элементе массива или

2) Причина в том, что каждая структура должна быть выровнена по 8-байтовой границе из-за требования естественного выравнивания для переменной типа структуры.

Чтобы прояснить мою точку зрения, каким должен быть начальный адрес первого члена массива? Если это 8-байтовый выровненный адрес, как указано во втором случае, это может быть проблемой при определении больших двумерных массивов, таких как:

int arr [1000] [1000];

Здесь каждый элемент двумерного массива (т.е. каждый одномерный массив) должен быть выровнен по границе в 4000 байт. У машины может не быть дыры в памяти для выполнения этого требования к памяти.


  • Какой язык программирования? 16.06.2013
  • Его C. Также, если я применяю sizeof к одному экземпляру структуры (не элементу массива структур), определенной отдельно, я получаю 8 байтов в качестве ответа, а не 5 байтов. Почему это так? Компилятор заполняется даже в случае одного экземпляра, когда память свободна после памяти, занятой экземпляром? 16.06.2013

Ответы:


1

Я не уверен, что понимаю разницу между двумя упомянутыми вами вариантами.

Каждый тип в C ++ имеет естественное выравнивание, кратное его размеру. Но выравнивание не обязательно равно размеру объекта.

Например, int обычно имеет естественное выравнивание 4 байта и размер 4 байта.

Но хотя массив из 1000 int имеет размер 4000 байтов, для него требуется всего лишь 4-байтовое выравнивание.

Составные типы (структуры и массивы) требуют только того же выравнивания, что и их наиболее выровненный элемент член. Массив из 1000 int содержит объекты только одного типа: int. И этот тип требует 4-байтового выравнивания, поэтому для всего массива также требуется только 4-байтовое выравнивание.

Точно так же для структуры вашего примера она имеет размер (обычно) 8 байтов, но состоит из int (для которого требуется 4-байтовое выравнивание) и char (для которого требуется 1-байтовое выравнивание). Следовательно, самое строгое выравнивание, требуемое для любого из его членов, равно 4, и поэтому структура требует 4-байтового выравнивания.

16.06.2013
  • Большое спасибо! Немного запутался в концепции. Также, если я применяю sizeof к одному экземпляру структуры (не элементу массива структур), определенной отдельно, я получаю 8 байтов в качестве ответа, а не 5 байтов. Почему это так? 16.06.2013
  • Да, это из-за другого правила, согласно которому между элементами в массиве не может быть отступов. Скажем, вы создаете массив своих структур. Каждый из элементов должен быть выровнен по 8-байтовой границе, но если бы размер был 5, то вместо этого второй элемент был бы размещен на 5-байтовой границе. Таким образом, чтобы гарантировать, что каждый элемент помещен на 8-байтовую границу, размер должен быть кратным требованию выравнивания. 16.06.2013
  • Хорошо .. понял! Большое тебе спасибо! 16.06.2013
  • Новые материалы

    Математика и интуиция - Часть 1
    У каждой математической формулы есть доказательство. Часто эти доказательства слишком сложно понять, поскольку многие из них основаны на индукции, некоторые - на очень сложных наблюдениях, а..

    Раскрытие возможностей НЛП: часть речевой маркировки и ее проблемы
    В сфере обработки естественного языка (NLP) маркировка частей речи (POS) выступает в качестве фундаментального метода, позволяющего компьютерам понимать и анализировать человеческий язык на..

    Под поверхностью: раскрытие деталей системы с помощью инструментов Linux CLI
    Чем больше вы изучаете Linux и продвигаетесь вперед, тем больше вам нужно проверять информацию о вашей системе. Эта информация может касаться аппаратного обеспечения, такого как процессор,..

    Как реализовать линейную регрессию в JavaScript
    Узнайте, как реализовать линейную регрессию в JavaScript с помощью ML.js Линейная регрессия — это метод машинного обучения, используемый для моделирования связи между зависимой переменной и..

    Рассвет или закат ?: как контекст будет направлять разработку ИИ для компьютерного зрения в медицинской визуализации
    Рассвет или закат ?: как контекст будет направлять разработку ИИ для компьютерного зрения в медицинской визуализации Посмотрите на картинку выше. Знаете ли вы, является ли это изображением..

    Запуск LF Internship v2 (1 апреля - 1 октября 2019 г.)
    Вот и открылись двери к великолепию 😃. Как и было обещано, заявки на стажировку принимаются с 7 января по 28 февраля 2019 г. . Нажмите ссылку, чтобы подать заявку:..

    BCACTF 4.0 Writeup — Freebee (Интернет)
    Описание вызова: Я хочу прочитать эту действительно классную статью, но у них есть платный доступ. Вы можете мне помочь? Веб-адрес вызова: http://challs.bcactf.com:30771/ . Если вы..