Другое событие 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));
}
Состояния пункта 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).
Элементы данных расположены в объявленном порядке. Компилятор является бесплатным вкрапить дополнение для расположения выравнивания памяти, которое это любит (и Вы найдете, что много компиляторов имеют полную нагрузку лодки спецификация выравнивания опции---полезный при смешивании битов, скомпилированных различными программами.).
См. также Почему doesn' t GCC оптимизируют структуры? .
<час>кажется, что этот ответ является несколько устаревшим для C++. Вы каждый день изучаете что-то. Спасибо aib, Nemanja.
В основном можно рассчитывать на это только для классов с стандартное расположение . Строго говоря стандартное расположение является C++ 0x вещь, но это действительно просто стандартизирует существующую практику /
Я не могу говорить за C++, но в C порядок, как гарантируют, будет тем же порядком в памяти, как объявлено в структуре.
Кроме дополнения для выравнивания, никакая оптимизация структуры не позволяется никаким компилятором (что я знаю) для C или C++. Я не могу говорить за классы C++, поскольку они могут быть другим зверем полностью.
Полагают, что Ваша программа взаимодействует через интерфейс с кодом системы/библиотеки Windows, но Вы хотите использовать GCC. Необходимо было бы проверить, что GCC использовала идентичный алгоритм оптимизации расположения, таким образом, все структуры будут упакованы правильно прежде, чем отправить их в скомпилированный код MS.
При просмотре связанных тем справа, я посмотрел этот вопрос . Я полагаю, что это может быть интересным угловым случаем при размышлении об этих проблемах (если это не более распространено, чем я понимаю).
Для перефразирования, если у Вас есть структура в C, который выглядит примерно так:
struct foo{};
и подкласс это как так в C++ (использующий единицу раздельной компиляции):
extern "C" foo;
struct bar: public foo{};
Тогда выравнивание памяти не обязательно будет тем же по причинам упоминания aib (даже среди компиляторов от того же поставщика).