——————————————1 ——————————————
Я собираю программу для ARM под управлением встроенного Linux. Первоначально я написал программу для C ++, так что есть некоторые operator new
а также operator delete
с в коде. Теперь, чтобы скомпилировать вещи с operator new
с и operator delete
Для типичной платформы ПК мне нужно указать конкретный аргумент для компоновщика (-lstdc ++). Я не знаю точно, что это делает.
Теперь, если я попытаюсь использовать эту опцию компоновщика с моим кросс-компилятором ARM, я сделаю ссылку правильно, но у меня не получится во время выполнения с этим сообщением:
Ld.so: dl-deps.c: 622 обнаружено несоответствие: _dl_map_object_deps: утверждение `nlist> 1 ‘не выполнено!
И если я опускаю опцию ссылки, я работаю нормально. Это похоже на провал утверждения, но это настолько далеко, насколько я был бы готов рискнуть предположить. Может ли кто-нибудь пролить свет на эту ошибку или ее вероятную причину?
————————————————2 ————————————
Я решил опустить опцию (-lstdc ++) и заменить все мои указатели классов на указатели на экземпляры переменных в стеке. Это работает, но это явно неаккуратно, и, поскольку это должно быть примером для студентов, я хочу, чтобы это было чисто. чистый способ сделать это было бы создать свой собственный operator new
а также operator delete
… но не очевидно, как бы я на самом деле использовал самоопределенные операторы.
Взять, к примеру, someClass * foo = new someClass(arg);
Это три (?) Шага.
Я не знаю порядок этих шагов. Я не знаю, как вызвать конструктор класса независимо от создания новой переменной этого типа в стеке. И я не знаю, как поместить новую переменную класса в кучу, где бы она ни начиналась.
Во-первых, исправление. Ваше заявление о создании выше — это два шага, а не три; конструктор класса применяется непосредственно к выделенной области памяти, чтобы превратить его из «случайной памяти» в экземпляр объекта. Иначе правильно, хотя.
Перегрузка оператора new относительно проста. Вам не нужно вызывать конструктор класса в операторе new; язык обрабатывает эти шаги отдельно. Оператор new () по сути является просто версией C ++ для malloc ():
void *operator new(std::size_t sz) {
void *out = ::malloc(sz);
if (!out) throw new std::bad_alloc();
return out;
}
Вышесказанное в основном имитирует реальный оператор new. Вам нужно настроить это, чтобы выполнить любые специальные операции, необходимые для того, чтобы ваш код мог поддерживать ARM. Здесь есть какая-то магия, так что будьте осторожны. После завершения оператора new () язык вызывает ваш конструктор класса, который может быть исключен. Если это так, C ++ требуется для освобождения памяти, выделенной оператором new () (поскольку у вас, программиста, нет ссылки на него и, следовательно, вы не можете освободить ее самостоятельно). Таким образом, C ++ волшебным образом вызовет оператор delete () в этом случае … но только если он может найти идеально подходящую версию.
TL; DR: если вы перегрузите оператор new (), всегда перегрузите оператор delete () и убедитесь, что они совпадают по сигнатуре, области действия и т. Д.
Других решений пока нет …