определяя мой собственный новый оператор

——————————————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); Это три (?) Шага.

  1. вызывающий оператор новый. выделяет некоторую память для нового экземпляра класса.
  2. вызывающий конструктор класса.
  3. помещая экземпляр класса в ячейку памяти, созданную оператором new

Я не знаю порядок этих шагов. Я не знаю, как вызвать конструктор класса независимо от создания новой переменной этого типа в стеке. И я не знаю, как поместить новую переменную класса в кучу, где бы она ни начиналась.

2

Решение

Во-первых, исправление. Ваше заявление о создании выше — это два шага, а не три; конструктор класса применяется непосредственно к выделенной области памяти, чтобы превратить его из «случайной памяти» в экземпляр объекта. Иначе правильно, хотя.

Перегрузка оператора 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 () и убедитесь, что они совпадают по сигнатуре, области действия и т. Д.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector