Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.
Например, ниже - класс ученика, который будет использовать его в нашем коде.
public class Student {
private int id;
public int getId() {
return this.id;
}
public setId(int newId) {
this.id = newId;
}
}
Приведенный ниже код дает вам исключение с нулевым указателем.
public class School {
Student obj_Student;
public School() {
try {
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Поскольку вы используете Obj_Student
, но вы забыли инициализировать его, как в правильном коде, показанном ниже:
public class School {
Student obj_Student;
public School() {
try {
obj_Student = new Student();
obj_Student.setId(12);
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
memset является способом пойти. У Вас нет многих альтернатив.
Делают что-то как:
#define InitStruct(var, type) type var; memset(&var, 0, sizeof(type))
Так, чтобы Вы только имели к:
InitStruct(st, BigStruct);
И затем используют Св., как обычно...
я не добираюсь, как "0" не допустимое "0" тип для структуры. Единственный путь к "массе инициализирует" структуру, должен установить всю ее память к значению; иначе необходимо было бы сделать дополнительную логику, чтобы сказать ему использовать определенную комбинацию двоичных разрядов на участника. Лучшая "универсальная" комбинация двоичных разрядов для использования 0.
, Кроме того - это - та же логика, которую Вы использовали при выполнении
*(controller->bigstruct) = *( struct bigstruct ){ 0 };
Поэтому, я не получаю нежелание использовать ее:)
первый комментарий к этому сообщению заставил меня провести некоторое исследование, прежде чем я позвонил ему и идиоту, и я нашел это:
http://www.lysator.liu.se/c/c-faq/c-1.html
Очень интересный; если я мог бы проголосовать за комментарий, я был бы:)
, Что быть сказанным - Ваша единственная опция, если Вы хотите быть нацеленными на архаичную архитектуру с не0 нулевыми значениями, должно все еще сделать ручную инициализацию определенным участникам.
Спасибо Thomas Padron-McCarthy! Сегодня я изучил что-то новое:)
Если Вы не хотите использовать memset, Вы могли бы всегда объявлять статическую копию своей структуры и использовать memcpy, который даст подобную производительность. Это добавит 4 megs к Вашей программе, но вероятно лучше, чем установка отдельных элементов.
Однако если бы GCC использовала memset, и это было достаточно хорошо ранее, я предположил бы, что это достаточно хорошо теперь.
Как другие сказали, memset является способом пойти. Однако не делают использование memset на объектах C++, особенно те с виртуальными методами. Эти sizeof( foo )
будет включать таблицу указателей виртуальной функции, и выполнение memset на этом вызовет серьезное горе.
, Если memset не решает проблему отдельно, просто сделайте memset и тогда инициализирует любых участников, которые должны быть ненулевыми (т.е. Ваши значения с плавающей точкой не-IEEE).
Частная функция инициализации не ужасна скорее хорошее OO способ инициализировать объекты (структуры). Я предполагаю, что Ваша структура не составляет 4 МБ указателей, таким образом, я предположил бы, что решение должно быть похожим на это:
void init_big_struct(struct bigstruct *s)
{
memset(s, 0, sizeof(struct bigstruct));
s->some_pointer = NULL; // Multiply this as needed
}
От другой руки наш код работает на более тогда 20 встроенных операционных системах и большом количестве различных аппаратных средств, никогда не встречайте проблему только с memset структуры.
хм - в первую очередь, создание функции init и установка каждого участника явно ЯВЛЯЮТСЯ ПРАВИЛЬНОЙ ВЕЩЬЮ - это, s путь конструкторы в работе языков OO.
и второй - кто-либо знает аппаратные средства, которые реализуют не числа с плавающей точкой IEEE? - возможно, Commodore 64 или somethig;-)