Страницы

Поиск по вопросам

суббота, 28 декабря 2019 г.

Вызов delete[] для nullptr не приводит к падению приложения? [дубликат]

#cpp


        
             
                
                    
                        
                            This question already has an answer here:
                            
                        
                    
                
                        
                            Удаление нулевого указателя
                                
                                    (1 ответ)
                                
                        
                                Закрыт 1 год назад.
            
                    
Почему мне подсвечиваются подсказки для массивов где я делаю проверку на nullptr
перед вызовом delete[], получаю подсказку о том что вызов delete[] для nullptr не производит
никаких эффектов?

Это правда, или это лишь поддержка с какого-то стандарта, или подсказка о том что
я в коде нигде не заполняю массив, и его можно спокойно удалять даже с значением nullptr?
    


Ответы

Ответ 1



Стандарт утверждает, что оператору delete (delete[]) можно смело передавать nullptr - просто в этом случае оператор не будет делать ничего (см. п. 5.3.5.2 стандарта). ...значение операнда delete может представлять собой нулевое указательное значение, либо указатель на объект-немассив, созданный посредством некоторого предыдущего new-выражения, либо быть указателем на подобъект (1.8) базового класса объекта-немассива (глава 10). В противном случае поведение программы не определено. Примерно то же говорится и для оператора delete[]: ...значение операнда операции delete может быть нулевым указательным значением, либо указателем, полученным в результате некоторой предыдущей операции new-выражение для массива.

Ответ 2



Ну, во-первых, операторы delete/delete [] в принципе невозможно вызвать ни с каким nullptr. nullptr имеет тип std::nullptr_t и использовать значение этого типа в качестве операнда этих операторов не получится. Операндом delete/delete [] должен являться либо указатель на объектный тип, либо класс, приводимый к такому указателю. Если указатель является null-указателем, то delete/delete [] просто ничего не делает. Null-указатель и nullptr - это совершенно разные вещи. Во-вторых, испокон веков в С и С++ (и далеко за их пределами) было принято придерживаться негласного соглашения о том, что средства освобождения ресурсов ничего не делают в ответ на нулевой хендл ресурса. Точно так же, как функция free() ничего не делает в ответ на null-указатель, операторы delete/delete[] ничего не делают в ответ на null-указатель. Этого негласного правила придерживаются во многих API. (fclose с этой точки зрения является неприятным исключением).

Нахождение угла между 2 точками (для движения машины к цели)

#c_sharp


Проблема такая:

Нужно найти угол между точками X, Y.

К примеру, есть точки:

Координаты машины:


  x: 1141.513916
  y: -1162.998169


Координаты точки, куда нужно ей приехать:


  x: 1162.112061
  y: -1199.149658


Нужно как-то рассчитать угол между машиной и точкой.

Должно быть что-то такое:

if (angel < 5){
  Turn_Car_Left();
}

if (angel == 5){
  Ride_Forward();
}

if (angel > 5){
  Turn_Car_Right();
}

    


Ответы

Ответ 1



Вступление Итак, начать стоит с того, что Вы поставили некорректное условие, так как угол - геометрическая фигура, образованная двумя лучами (сторонами угла), выходящими из одной точки (которая называется вершиной угла). В свою очередь луч - часть прямой, состоящая из данной точки и всех точек, лежащих по одну сторону от неё. Любая точка на прямой разделяет прямую на два луча. В свою же очередь одна единственная прямая проходит через 2 точки => для построения угла требуется части 2-х пересекающихся прямых (с одной общей точкой) => 2 * 2 - 1 = 3 точки Таким образом мы получаем очевидный для всех факт: не может быть между двумя точками какого-либо угла Немного теории Отойдем ненадолго от разъяснений геометрии за N класс средней школы и все таки попытаемся догадаться, что же Вам нужно Как я понимаю, Вы моделируете движение машины в плоскости xOy. Так как машина движется, она имеет некоторый вектор, характеризующий ее перемещение. Предположу, что машина выехала из точки (0; 0) => если ее текущие координаты равны (x; y), то вектор перемещения равен { x - 0; y - 0; } = { x; y; } Однако так как Вам требуется найти угол для поворота машины, Вам бы следовало использовать вектор ее скорости, но Вы нас обделили информацией о нем, так что предположу, что он сонаправлен с вектором перемещения Итак. На данном шаге у нас есть вектор и точка, итого: 3 точки. Для расчета угла более чем достаточно Далее находим направляющий вектор из начала координат в необходимую точку и находим наименьший угол между двумя имеющимися векторами (a и b) по формуле: cos(α) = (a * b) / (|a| * |b|) Пример Попробуем на примере: Пусть машина располагается в точке (1; 2.5), а пункт назначения - в точке (3; 3): a = { 1; 2.5 } b = { 3; 3 } cos(α) = (1*3 + 2.5*3) / (sqrt(1*1 + 2.5*2.5) * sqrt(3*3 + 3*3)) ≈ 0.91914503001 => α = arccos(0.91914503001) ≈ 0.404891786 rad ≈ 23.1985905 deg Вот мы и получили заветный угол, который примерно равен 23 градусам На сием курс геометрии окончен, переходим к программной реализации Реализация Набросаем такую функцию: private static double GetAngle(Point Machine, Point Destination) { // Получим косинус угла по формуле double cos = Math.Round((Machine.X * Destination.X + Machine.Y * Destination.Y) / (Math.Sqrt(Machine.X * Machine.X + Machine.Y * Machine.Y) * Math.Sqrt(Destination.X * Destination.X + Destination.Y * Destination.Y)), 9); // Вернем arccos полученного значения (в радианах!) return Math.Acos(cos); } Судя по значениям в Вашем примере, которые явно больше единицы, Вы используете не радианную, а градусную меру, а посему значение, которое вернет Вам функция, необходимо будет преобразовать по формуле: dAngle = rAngle * 180 / Pi То есть так: // Переведем угол в градусы private static double ToDegrees(double Angle) => Angle * 180 / Math.PI; Протестируем: Пусть машина располагается в точке (-3; -3), а пункт назначения - в точке (3; 3): Найдем угол: Console.WriteLine(ToDegrees(GetAngle(new Point(-3, -3), new Point(3, 3)))); // 180 180 градусов, что, очевидно, является чистейшей правдой! Итоги Старайтесь не забывать, что программирование состоит не только из набора текста, но и из применения знаний некой предметной области, с которой Вы соприкасаетесь в рамках проекта. Чего-то не знаете? Читайте и узнавайте по теме как можно больше! И да, подчеркну, что представленный выше метод будет работать только если Ваша машинка прямолинейно удаляется от начала координат (т.е. векторы перемещения и скорости сонаправлены), однако стоит машине развернуться и поехать в сторону точки (0; 0), как все сломается! Чтобы решить проблему, Вам необходимо знать, в какую сторону движется автомобиль. Я не знаю деталей Вашей реализации, так что могу предложить кэшировать предыдущую точку, в которой был автомобиль, после чего уже передвигать его на новую. Тем самым Вы спокойно в любой момент времени найдете вектор скорости машины и примените его в расписанном выше алгоритме

Ответ 2



Считаю, что дано: S: точка, координаты машины D: вектор направления машины T: целевая точка Тогда целевой вектор V = T - S //или в компонентах: V.X = T.X - S.X V.Y = T.Y - S.Y Угол между текущим направлением машины и целевым вектором A = atan2(D x V, D * V) //векторное и скалярное произведение векторов //или в компонентах: A = atan2(D.X * V.Y - D.Y * V.X, D.X * V.X + D.Y * V.Y) Результат - угол в радианах в диапазоне -Pi..Pi, на который нужно повернуть машину, чтобы мгновенный вектор её направления указывал на цель. Знак угла соответствует левому или правому повороту. (физику (инерцию и т.д.), как я понял, не учитываем)

Android - в связи с прекращением существования системы, стоит ли изучать Kotlin?

#java #android #kotlin #fuchsia


Как уже пишут, система Android в 2023-м году будет заменена на новую операционную
систему, и все устройства уже будут выпускаться без Android.

Так как сегодня язык программирования Kotlin только начинает свое развитие, и многие
библиотеки пока еще на Java, стоит ли браться за изучение Kotlin, если есть какой-то
опыт в Java? Даже если в ближайшие 2-3 года Kotlin станет основным языком в Android
программировании, каков будет смысл изучать его, если он вскоре не будет нужен?
    


Ответы

Ответ 1



Даже если Android и будет заменен на Fuchsia или что-там еще, то надо четко понимать, что 70-80% успеха новой оси это наличие девелоперов, разработчиков под данную ось. Нет разработчиков - нет приложений, нет приложений нет оси. Уже многие пытались: HP выпускал WebOS, Samsung выпускал Tizen и что? Где они теперь? Если Google не сделает ставку на Java девелоперов - ось не взлетит. Другой вопрос, что лет через 5 возможно появится другой язык программирования, который начнет доминировать. Сейчас многие активно пересаживаются на Kotlin, но надо понимать, что Kotlin это та же самая Java только в профиль, я вот лично Kotlin от Java почти не отделяю. Следите за рэнкингом языков На мой пристрастный взгляд сейчас есть 2 перспективных языка: Python и Rust, первый потому что все вдруг резко увлеклись AI, ML и проч. модностями, а второй - ну не знаю, свежо как то :)

Ответ 2



Не факт, что Android будет заменен. Fucsia - пока только пробный проект. Второе - обещали поддержку приложений из Google Play. Скорее всего, будет и поддержка Java-Kotlin приложений. А Kotlin в любом случае надо учить, даже если случится такое, что Fucsia выстрелит и программировать под нее будет нельзя на Kotlin`e, то в мире останется миллионы Android устройств. Да и пока ждешь до 2033-35 надо что-то делать...

Ответ 3



Как уже известно, готовящаяся на замену Android ОС Fuchsia будет базироваться на Flutter SDK. Недавно вышла статья на тему использования Kotlin c Flutter SDK. Пока не все гладко и есть существенные ограничения, но впереди еще пять лет и ответ на ваш вопрос по поводу нужности данного языка, думаю, очевиден.

не срабатывает счетчик python

#python #python_3x


Дан массив из строк, которые содержат смайлики, типа:

[':D',':~)',';~D',':)']


Нужно определить, сколько смайликов "с улыбкой"
Улыбкой считаются такие:

:) :D ;-D :~)


Алгоритм:

def count_smileys(arr):
    num = 0
    for i in range(len(arr)):
        if ")" or "D" in arr[i]:
            num =+ 1
    return num


Вот только, если подать аргументом функции строку с примером выше, мой num насчитает
только 1, а не 4.
Причем все итерации проходят.

Как оказалось,надо учитывать, что у смайлика должны быть:
одни из таких  "глаз" ;:
один из таких "носов"(или его отсутствие) -~ 
и одна из таких "улыбок" )D .  

Я пробовал через регулярные выражения:

return int(len(re.findall('[:;][-~]?[)D]', arr)))


но это так же не срабатывает, вываливаясь с ошибкой
expected string or bytes-like object
    


Ответы

Ответ 1



Попробуйте: def count_smileys(arr): num = 0 for x in arr: if ")" in x or "D" in x: num += 1 return num smileys = [':D', ':~)', ';~D', ':)'] print(count_smileys(smileys)) # 4 Вариант через регулярное выражение: import re def count_smileys(arr): num = 0 for x in arr: if re.match('[;:][-~]?[)D]', x): num += 1 return num # Вариант в одну строку: def count_smileys(arr): return sum(bool(re.match('[;:][-~]?[)D]', x)) for x in arr) smileys = [':D', ':~)', ';~D', ':)', ':(', ':(D'] print(count_smileys(smileys)) # 4

Ответ 2



Думаю проблема все-таки в "+=" def count_smileys(arr): num = 0 for i in arr: if ")" in i or "D" in i: num += 1 return num И, как уточнили, проблема также в строении логического выражения

Ответ 3



Чтобы понять что происходит можно воспользоваться модулем dis (disassembler): In [367]: dis.dis('")" or "D" in ":-D"') 1 0 LOAD_CONST 0 (')') 2 JUMP_IF_TRUE_OR_POP 10 # прыгаем на строку 10, т.к. первый аргумент в `OR` вернет истину 4 LOAD_CONST 1 ('D') 6 LOAD_CONST 2 (':-D') 8 COMPARE_OP 6 (in) >> 10 RETURN_VALU У вас в коде две ошибки - вторую хорошо описал @TenDaI, если ее исправить то ваш код будет всегда возвращать число строк в массиве, независимо от их содержимого

Ответ 4



Я бы сделал несколько по-другому: a = [':D',':~)',';~D',':)'] res = (''.join(a)).count(')')+ (''.join(a)).count('D') либо, ещё лучше: smileys = [')', 'D'] for _ in smileys: res += (''.join(a)).count(_) print(res) При таком подходе не нужно лезть внутрь цикла, если придется менять критерии поиска.Единственный минус - такой подход не сработает для поиска смайлов типа ':)))'

Декораторы Python

#python #python_3x #декоратор


Поясните, пожалуйста, следующее высказывание, желательно с примерами. Я новичок и
никак не могу осилить эти декораторы.


  Декораторы могут быть использованы для расширения возможностей функций из сторонних
библиотек (код которых мы не можем изменять).

    


Ответы

Ответ 1



Предположим, что в душе вы настоящий римлянин и вам неудобны варварские цифры, которые использует Python. Есть способ преобразовывать варварские цифры в римские и обратно - модуль roman. Но чтобы использовать его со стандартными функциями, такими как min и max, придётся писать код преобразований перед каждым вызовом. Типа: min_number = toRoman(min(fromRoman('VII'), fromRoman('X'))) Неудобно и неблаговидно! Поможет декоратор: from functools import wraps def romanize(f): @wraps(f) def wrapper(*args, **kwargs): return toRoman(f(tuple(fromRoman(i) for i in args), **kwargs)) return wrapper Декорируем интересующие функции min = romanize(min) max = romanize(max) И теперь в любом месте кода можем использовать их с римскими цифрами: min_number = min('VII', 'X')

Как узнать сколько жестких(или ssd) дисков установлено и какая у них вместимость?

#linux #ubuntu


Какой командой узнать сколько физических дисков установлено и какая у них вместимость?
Не смонтированные разделы, а именно физические устройства.
    


Ответы

Ответ 1



Есть симпатичная утилитка lsblk, обычно присутствует в штатной поставке, которая может нарисовать дерево использования устройств, например: melkij@melkij:~$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 298,1G 0 disk ├─sda2 8:2 0 298G 0 part │ ├─sysvg-home 254:1 0 186,3G 0 lvm /home │ └─sysvg-root 254:0 0 15G 0 lvm / └─sda1 8:1 0 94M 0 part /boot У меня стоит 1 диск 320гб (298ГиБ), один раздел на нём смонтирован в /boot, поверх второго развёрнут LVM Либо, например, запросить lsblk --nodeps NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 298,1G 0 disk Покажет только устройства, но не разделы на них и прочие LVM. Важная оговорка - это всё если устройства распознаны операционной системой и между ними и системой нет ничего дополнительного. Если накопители подключены через RAID контроллер - то обычно система видит только сам контроллер. А какие там на самом деле диски - необходимо уточнять через софт этого контроллера.

Ответ 2



lshw - list hardware (тут матчасть). sudo lshw -class disk

Ответ 3



Если есть желание обойтись без сторонних утилит, то можно так: grep -r . /sys/block/sd?/size Размер выводится в 512-байтовых блоках. Также, как и все остальные способы, этот не различает жёсткий диск от флешки или кард ридера.

Как получить информация о сеансах работы с БД в которых есть незакрытые транзакции?

#sql #oracle #oracle11g


Как из представлений словаря данных (насколько понимаю, нужно обращаться к v$session
и v$transaction и делать выборку v$session.sid и v$session.username) получить информацию
обо всех сеансах работы с БД, в которых есть незакрытые транзакции? 

Например, через консоль и SQL*Plus в виде двух колонок - ид сеанса и имя пользователя.

Для определения незакрытых транзакций можно ли использовать ограничение v$transaction.flag=7811?
Например, так:

SELECT v$session.sid, v$session.username
FROM v$session, v$transaction
WHERE v$transaction.flag=7811;


Версия: Oracle Database 11g Release 2
    


Ответы

Ответ 1



Попробуйте так: select s.sid, s.serial#, s.username from v$transaction t inner join v$session s on t.addr = s.taddr ; no rows selected select 1 from t1 for update; select s.sid, s.serial#, s.username from v$transaction t inner join v$session s on t.addr = s.taddr ; SID SERIAL# USERNAME ---------- ---------- ---------- 34 55338 OE Следует учесть, что "незакрытые транзакции" не означает, что произошли изменения данных. В примере выше, например, запрос с for update ничего не изменил.

Ответ 2



@0xdb уже показал вам как посмотреть все транзакции. Иногда бывает полезным найти только тех пользователей и их сессии, которые блокируют какие либо объекты БД (таблицы, индексы и т.д.): set lines 200 pages 200 col inst_id for 99 col obj for a45 col lock_mode for a16 col blocker_sid_serial_sqlid for a45 col os_user_pid for a18 col machine for a30 break on blocker_sid_serial_sqlid skip page select l.inst_id as inst_id ,o.owner||'.'||o.object_name as obj ,case l.locked_mode when 0 then '0:none' when 1 then '1:null (NULL)' when 2 then '2:row-S (SS)' when 3 then '3:row-X (SX)' when 4 then '4:share (S)' when 5 then '5:S/Row-X (SSX)' when 6 then '6:exclusive (X)' else to_char(l.locked_mode) end as lock_mode ,l.oracle_username||' ('||s.sid||','||s.serial#||') ['||s.sql_id||']' as blocker_sid_serial_sqlid ,l.os_user_name||' ['||l.process||']' as os_user_pid ,s.machine from gv$locked_object l join dba_objects o on l.object_id = o.object_id join gv$session s on (s.sid = l.session_id and s.inst_id=l.inst_id) /* where o.owner like '&&OWNER.%' */ order by inst_id, blocker_sid_serial_sqlid, obj ;