Участники класса/структуры всегда становятся созданными в памяти в порядке, которым они были объявлены?

Другое событие NullPointerException возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.

String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals для гарантированного непустого объекта.

Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null.

Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.

String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

41
задан Community 23 May 2017 в 12:32
поделиться

6 ответов

Состояния пункта 13 C99 В§6.7.2.1:

В объекте структуры, у non-bit-п¬Ѓeld участников и единиц, в котором бите-п¬Ѓelds находятся, есть адреса, которые увеличиваются в порядке, в котором они объявляются.

и продолжает немного больше о дополнении и адресах. Эквивалентный раздел C89 является В§6.5.2.1.

C++ немного более сложен. В стандартах 1998 и 2003 годов существует В§9.2 пункт 12 (пункт 15 в C++ 11):

Нестатические элементы данных (не состоящего в профсоюзе) класса, объявленного без прошедшего спецификатора доступа, выделяются так, чтобы у более поздних участников были более высокие адреса в объекте класса. Порядок выделения нестатических элементов данных, разделенных спецификатором доступа, неуказанный (11.1). Требования выравнивания реализации могли бы заставить двух смежных участников не быть сразу выделенными друг после друга; так могли бы требования для пространства для управления виртуальными функциями (10.3) и виртуальные базовые классы (10.1).

72
ответ дан aib 27 November 2019 в 00:31
поделиться

Элементы данных расположены в объявленном порядке. Компилятор является бесплатным вкрапить дополнение для расположения выравнивания памяти, которое это любит (и Вы найдете, что много компиляторов имеют полную нагрузку лодки спецификация выравнивания опции---полезный при смешивании битов, скомпилированных различными программами.).

См. также Почему doesn' t GCC оптимизируют структуры? .

<час>

кажется, что этот ответ является несколько устаревшим для C++. Вы каждый день изучаете что-то. Спасибо aib, Nemanja.

4
ответ дан Community 27 November 2019 в 00:31
поделиться

В основном можно рассчитывать на это только для классов с стандартное расположение . Строго говоря стандартное расположение является C++ 0x вещь, но это действительно просто стандартизирует существующую практику /

3
ответ дан Nemanja Trifunovic 27 November 2019 в 00:31
поделиться

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

2
ответ дан Chris Young 27 November 2019 в 00:31
поделиться

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

Полагают, что Ваша программа взаимодействует через интерфейс с кодом системы/библиотеки Windows, но Вы хотите использовать GCC. Необходимо было бы проверить, что GCC использовала идентичный алгоритм оптимизации расположения, таким образом, все структуры будут упакованы правильно прежде, чем отправить их в скомпилированный код MS.

2
ответ дан Jason Baker 27 November 2019 в 00:31
поделиться

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

Для перефразирования, если у Вас есть структура в C, который выглядит примерно так:

struct foo{};

и подкласс это как так в C++ (использующий единицу раздельной компиляции):

extern "C" foo;
struct bar: public foo{};

Тогда выравнивание памяти не обязательно будет тем же по причинам упоминания aib (даже среди компиляторов от того же поставщика).

0
ответ дан Community 27 November 2019 в 00:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: