Сергей Борщ 134 9 сентября, 2016 Опубликовано 9 сентября, 2016 · Жалоба А мне хочется и другой вариант попробовать, складывать команды в очередь пока есть свободная память, а потом, те что не влезают, выкидывать.У меня в таком случае в перегруженном operator new() из очереди удаляются самые старые события (которые, наверняка, уже мало кому интересны) и после каждого удаления производится повторная попытка выделить память для нового события. Если очередь уже пуста, а памяти все еще не хватает - то, значит, что-то уже сильно порушено и остается только перезагружаться. С обычным new это невозможно. А с operator new ( std::size_t count, const std::nothrow_t& tag) - возможно. В этом случае компилятор вставляет проверку возвращенного new(std::nothrow) указателя и вызывает конструктор только в том случае, если new вернул не 0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Terminator 0 10 сентября, 2016 Опубликовано 10 сентября, 2016 · Жалоба У меня в таком случае в перегруженном operator new() из очереди удаляются самые старые события (которые, наверняка, уже мало кому интересны) и после каждого удаления производится повторная попытка выделить память для нового события. Если очередь уже пуста, а памяти все еще не хватает - то, значит, что-то уже сильно порушено и остается только перезагружаться. Такой подход требует реализации собственного, аля, сборщика мусора. А с operator new ( std::size_t count, const std::nothrow_t& tag) - возможно. В этом случае компилятор вставляет проверку возвращенного new(std::nothrow) указателя и вызывает конструктор только в том случае, если new вернул не 0. Почти так и сделал. С std::nothrow сделать не получилось. Сделал проще, operator new(size_t,void*). Кстати, компилятор никаких проверок не вставляет, конструктор вызывается в любом случае. Вставил проверку перед вызовом new. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 10 сентября, 2016 Опубликовано 10 сентября, 2016 · Жалоба Почти так и сделал. С std::nothrow сделать не получилось. Сделал проще, operator new(size_t,void*).Проще? Покажите, сравним. Это так по-русски - чуть что, придумывать свой велосипед. Причем почти всегда с квадратными колесами. Кстати, компилятор никаких проверок не вставляет, конструктор вызывается в любом случае.У меня вставляет, что я делаю неправильно? #include <new> class a { public: a(); }; a * pA; void test() { pA = new(std::nothrow) a; } 18:main.cpp **** void test() 19:main.cpp **** { 100 .loc 1 19 0 101 .cfi_startproc 102 @ args = 0, pretend = 0, frame = 0 103 @ frame_needed = 0, uses_anonymous_args = 0 104 0000 10B5 push {r4, lr} @ 105 .LCFI0: 106 .cfi_def_cfa_offset 8 107 .cfi_offset 4, -8 108 .cfi_offset 14, -4 20:main.cpp **** pA = new(std::nothrow) a; 109 .loc 1 20 0 110 0002 0549 ldr r1, .L7 @, 111 0004 0120 movs r0, #1 @, 112 0006 FFF7FEFF bl _ZnwjRKSt9nothrow_t @ <-------- new(std::nothrow) 113 .LVL0: 114 000a 0446 mov r4, r0 @ D.8513, 115 000c 08B1 cbz r0, .L2 @, <------- проверка 116 .loc 1 20 0 is_stmt 0 discriminator 1 117 000e FFF7FEFF bl _ZN1aC1Ev @ <------- вызов конструктора 118 .LVL1: 119 .L2: 120 .loc 1 20 0 discriminator 4 121 0012 024B ldr r3, .L7+4 @ tmp112, 122 0014 1C60 str r4, [r3] @ D.8513, pA 123 0016 10BD pop {r4, pc} @ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 11 сентября, 2016 Опубликовано 11 сентября, 2016 · Жалоба кусочек кода и конструктор int main(void) { EngineTask = new TEngineTask() ; ...... ........... class TEngineTask : public TTask { public: TEngineTask () { NOP(); active = false ; NOP(); } ......... ВАЖЕН атрибут которым оператор new помечен: inline void* operator new(size_t size) 398 __libc_init_array() ; 0800a82a: bl 0x800aec0 <__libc_init_array> 0800a82e: movs r0, #12 <-------- выхов main() 0800a830: bl 0x800a394 <malloc(size_t)> <-------- EngineTask = new TEngineTask() ; 0800a834: movs r5, #0 <-------- вызов конструктора 0800a836: ldr r3, [pc, #248] ; (0x800a930 <ResetHandler()+744>) 0800a838: str r3, [r0, #0] 0800a83a: str r5, [r0, #4] 0800a83c: nop 14 active = false ; 0800a83e: strb r5, [r0, #8] 15 NOP(); 0800a840: nop 0800a842: ldr r3, [pc, #240] ; (0x800a934 <ResetHandler()+748>) нет проверки результата malloc , компилятор полагает механизм генерации исключений - при вызове по нулю конструктора код перехватит эксепшен и все ок. inline void* operator new(size_t size) _GLIBCXX_NOEXCEPT 398 __libc_init_array() ; 0800a82a: bl 0x800aec4 <__libc_init_array> 0800a82e: movs r0, #12 <-------- выхов main() 0800a830: bl 0x800a394 <malloc(size_t)> <-------- EngineTask = new TEngineTask() ; 0800a834: cbz r0, 0x800a844 <ResetHandler()+508> <-------- проверка того что вернул malloc 12 { 0800a836: ldr r2, [pc, #252] ; (0x800a934 <ResetHandler()+748>) <- вызов конструктора 0800a83a: stmia.w r0, {r2, r3} 13 NOP(); 0800a83e: nop 14 active = false ; 0800a840: strb r3, [r0, #8] 15 NOP(); 0800a842: nop 0800a844: ldr r3, [pc, #240] ; (0x800a938 <ResetHandler()+752>) компилятор полагает что new не генерит эксепшенов и поэтому нужно проверить результат malloc чтоб не улететь в космом Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 11 сентября, 2016 Опубликовано 11 сентября, 2016 · Жалоба EngineTask = new TEngineTask(); pA = new(std::nothrow) a; Найдите десять отличий. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 11 сентября, 2016 Опубликовано 11 сентября, 2016 · Жалоба Найдите десять отличий. Насколько я понял, klen привёл третий вариант, в котором void* operator new(size_t size) объявлен как noexcept. В этом случае компилятор тоже вставляет проверку результата выделения памяти перед вызовом конструктора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Terminator 0 12 сентября, 2016 Опубликовано 12 сентября, 2016 · Жалоба Проще? Покажите, сравним. Это так по-русски - чуть что, придумывать свой велосипед. Причем почти всегда с квадратными колесами. Согласен, с "проще" я несколько погорячился :) Просто с обычным new(std::nothrow) у меня проект не собирается, зачем-то тащит библиотечную "кучу" и что-то про исключения. Вот мой код. void* __mem = malloc(sizeof(Packet)); if (__mem == nullptr) { ... } else { packet = new(__mem) Packet(...); ... переопределение new void* operator new(size_t size, void* p) { (void) size; return p; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 12 сентября, 2016 Опубликовано 12 сентября, 2016 · Жалоба Насколько я понял, klen привёл третий вариант, в котором void* operator new(size_t size) объявлен как noexcept. В этом случае компилятор тоже вставляет проверку результата выделения памяти перед вызовом конструктора.Но это же велосипед. Уже существующий new(std::nothrow_t) делает ровно то же самое, всегда есть в заголовочном файле <new> любого компилятора и к нему там всегда приписан нужный правильный атрибут. Используя его не нужно думать, _GLIBСXX или какой еще _NOEXCEPT туда надо дописывать (хватает, кстати, обычного переносимого throw() ). Каюсь, тоже использовал такое переопределение, хоть это и грязный хак. Знакомый со стандартом программист, глядя в такой исходник и не зная о переопределении, вправе ожидать совершенно другого поведения кода. Это примерно равносильно #define true false, поэтому советовать такое кому-то еще я никогда не буду. Просто с обычным new(std::nothrow) у меня проект не собирается, зачем-то тащит библиотечную "кучу" и что-то про исключения.Странно. Для new() ему нужен malloc(), для delete() - free(), если эти две функции определены в проекте - у меня ничего не тащит. Можете сделать и выложить простейший проект? переопределение newВелосипед, такой велосипед ;) If placement_params are provided, they are passed to the allocation function as additional arguments. Such allocation functions are known as "placement new", after the standard allocation function void* operator new(std::size_t, void*), which simply returns its second argument unchanged. This is used to construct objects in allocated storage: Кстати, чтобы не писать (void)size; вы можете опустить имя первого параметра в определении функции: void* operator new(size_t, void* p) { return p; } И попробуйте все же победить, ваш код станет еще проще: packet = new(std::nothrow) Packet; if (packet == nullptr) { ... } else { ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 12 сентября, 2016 Опубликовано 12 сентября, 2016 · Жалоба Но это же велосипед. Уже существующий new(std::nothrow_t) делает ровно то же самое, всегда есть в заголовочном файле <new> любого компилятора и к нему там всегда приписан нужный правильный . Знакомый со стандартом программист, глядя в такой исходник и не зная о переопределении, вправе ожидать совершенно другого поведения кода. Это примерно равносильно #define true false, поэтому советовать такое кому-то еще я никогда не буду. я с Вами полностью согласен - нужно правильно уметь использовать стандарт. если он позволяет сделать что то - то делать именно его инструментом а не велосипедом. но у меня следующие мысли, первое - переопределение сокращает запись - везде писать new(std::nothrow_t) вместо new. второе более интересное. в принципе не сложно в своем коде писать new(std::nothrow_t) - это даже правильно как Вы заметили. нам повезло с STL - разработчтки контейнеров и прочего добра требующих динамического распределения памяти грамотно не стали пользоваться операторами new и delete - вместо этого каждый класс требует специальный класс аллокатора - который мы уже тут в хидере определили как нам нужно. все вроде бы хорошо ... остается вопорос - а что если в проект чужая либа в исходниках компилится и линкуется? там прийдется все new переправлять на new(std::nothrow_t), поэтому велосипед пока актуален на мой взгляд. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 12 сентября, 2016 Опубликовано 12 сентября, 2016 · Жалоба klen, как там с падением компилятора на исходниках с ключами под Cortex-A9? Нужна ли дополнительная информация для лечения бага? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 12 сентября, 2016 Опубликовано 12 сентября, 2016 · Жалоба klen, как там с падением компилятора на исходниках с ключами под Cortex-A9? Нужна ли дополнительная информация для лечения бага? еще не занимался, на работе жоппа, выходные ночевал на работе...я не забыл. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 18 сентября, 2016 Опубликовано 18 сентября, 2016 · Жалоба релизная сборка 6.2.0 linux64: http://klen.org/Files/DevTools/x86_64-kgp-....2.0_CORYLUS.7z win64: http://klen.org/Files/DevTools/x86_64-kgp-....2.0_CORYLUS.7z 2_Genadi Zawidowski проверяйте! сборка под линух у меня пережевала Ваш фалик :) сборка под масдай под wine тоже wine ./arm-kgp-eabi-gcc.exe -c -mcpu=cortex-a9 -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -fno-math-errno -funroll-loops -fgraphite -ffunction-sections -fdata-sections -ffat-lto-objects -Ofast -flto -gdwarf-2 -fomit-frame-pointer -Wall -Wstrict-prototypes -DNDEBUG=1 -DCPUSTYLE_R7S721=1 -DCPUSTYLE_R7S721020=1 -I../ -I../rza1x_inc usbd.c -o usbd.o объектники бинарно идентичны :) должно взлететь! Вы С++ используете? если да то используете ли исключения (try{} catch() )? если да то есть тонкие замечание пл кодогенерации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 19 сентября, 2016 Опубликовано 19 сентября, 2016 (изменено) · Жалоба С++ используете? Не использую. Скачал, проверил - на компиляции для A9 не сыпется. Работоспособность пока неначем проверять. Изменено 19 сентября, 2016 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 19 сентября, 2016 Опубликовано 19 сентября, 2016 · Жалоба Не использую. Скачал, проверил - на компиляции для A9 не сыпется. Работоспособность пока неначем проверять. для A9 по хорошему собрать отдельную сборку. у меня самого есть рабочая машинка на i.MX6Q. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 19 сентября, 2016 Опубликовано 19 сентября, 2016 · Жалоба Решил попробовать Вашу сборку под винду. Не находит либу: libc_nano.a Вы по идеологическим причинам их не собираете? Так невозможно сравнить Вашу сборку со сборками с ланчпада... А вообще проект компилируется нормально, но не собирается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться