• Столкнулся с непонятным - откуда лишние 00000002?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Python
    Седой и строгий
    Ответ написан
    Комментировать
  • Задание функции с помощью массива точек, возможные решения, литература?

    vfreelancer
    @vfreelancer
    php
    гуглите интерполяционный многочлен
    Ответ написан
    Комментировать
  • Как правильно освобождать память?

    @MarkusD Куратор тега C++
    все время мелю чепуху :)
    Давай рассмотрим, для начала, строку под комментарием.

    ArrayArray[0] = *new Array<int>{10};
    Что тут происходит.
    ArrayArray[0] вернет ссылку на Array<int>.
    *new Array<int>{10} выделяет память в куче под Array<int>, вызывает инициализатор Array<int>::Array(int length), после чего делает разыменование получившегося указателя на Array<int>.
    После этого для подготовленной ссылки на Array<int> будет выполнен оператор копирования по умолчанию, функциональность которого просто скопирует поля из объекта справа в объект слева от присвоения.
    После этого результат new Array<int>{10} становится утекшим, т.к. указатель на него сразу становится потерян и освободить занимаемую им память становится невозможно.
    Именно поэтому с этой строчкой у тебя "всё отрабатывает нормально". И нет, всё у тебя не отрабатывает нормально потому что память утекла.

    Давай рассмотрим следующую строку.

    ArrayArray[0] = Array<int>{10};
    Что тут происходит.
    ArrayArray[0] вернет ссылку на Array<int>.
    Array<int>{10} инициализирует безымянный локальный объект на стеке, используя инициализатор Array<int>::Array(int length).
    После этого выполняется уже оператор перемещения по умолчанию, суть которого снова сводится к копированию полей из объекта справа в объект слева. После этого оба объекта ссылаются на одну и ту же выделенную память через поле T *m_data.
    Далее безымянный локальный объект уничтожается, освобождая недавно выделенную память. А ArrayArray[0] в этот момент начинает ссылаться на освобожденную память.

    Double deletion происходит тогда, когда ArrayArray в конце работы программы пытается удалить уже освобожденную память в ArrayArray[0].

    В твоем коде на лицо нарушение инварианта типа.
    Что нужно сделать.
    Тебе должно уже стать понятно что проблема в твоем коде связана с поведением операторов копирования и перемещения по умолчанию. Но проблема у тебя, на самом деле, значительно шире. Потому что завтра ты ведь точно захочешь еще и инициализацию копией провести или вернуть объект по значению из функции. В этом случае тебя тоже ждут проблемы.
    Решением твоих проблем будет соблюдение правила 3/5/0.
    Тебе нужно полноценно описать поведение объектов при копировании, перемещении, а так же при инициализации копией и инициализацией через перемещение.
    Ответ написан
    2 комментария
  • Как называется подобная задача?

    @Akela_wolf
    Extreme Programmer
    Экстраполяция.

    В данном случае данных маловато, все что можно сделать - это линейную экстраполяцию. То есть на 25% приходится (2000-30) = 1970. А значит при 50% это будет -1940. Но это на уровне
    extrapolating.png
    Ответ написан
    1 комментарий
  • Координаты (широта и долгота) в x и y?

    hint000
    @hint000
    у админа три руки
    Не выходит
    Вышло бы только в случае ориентированного по сторонам света прямоугольника (т.е. верх строго на север, низ строго на юг, право строго на восток, лево строго на запад).

    Если размер карты небольшой и кривизной земной поверхности можно пренебречь,
    ...то можно использовать аффинное преобразование.
    https://www.google.com/search?q=аффинные+преобразо...
    Также можете посмотреть более сложный метод.

    Я писал такой алгоритм, вернее код на C++, но это было примерно 20 лет назад. На досуге попробую поискать в залежах хлама на дисках, но пока ничего не обещаю, так что возможно, вы разберётесь и напишете быстрее, чем я найду. :)
    Ответ написан
    3 комментария
  • Как программисты хранят частоиспользуемые куски кода, чтобы каждый раз не вспоминать заново?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Программисты такое не забывают, чтобы где-то хранить. Забыть можно названия функций, коих 100500 в различных API. Но синтаксис и стандарты языка - это как бы алфавит. Вот вы часто забываете алфавит? Сможете сейчас его воспроизвести: "а", "б", "в"... ? А если другой язык: "a", "b", "c"... ? Также и (настоящие) программисты помнят подобное, как основы основ.

    Частоиспользуемый код оформляется в виде функций, и пропадает необходимость в копировании/переписывании. Многие такие простые функции входят в стандартную библиотеку, и названия таких функций практически не меняются от языка к языку. Поэтому даже если в языке не оказалось одной из таких функций, то она создаётся с заранее известным названием, которое программисты помнят хорошо. А если функция специфична для проекта, то таких функций не много, и их тоже легко помнить (на время работы с проектом).
    Ответ написан
    Комментировать
  • Как рендерят видео с множеством Мальдеброта?

    AgentSmith
    @AgentSmith
    Это мой правильный ответ на твой вопрос
    На шейдерах можно сделать
    https://www.shadertoy.com/view/4df3Rn
    Ответ написан
    Комментировать
  • Как вывести TCHAR в файл?

    @galaxy
    Что возвращает функция GetComputerName? (как вообще этот код скомпилировался, интересно?)
    Ответ написан
    5 комментариев
  • Падает программа при вызове PInvoke?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    Ну как минимум ты на стороне C++ вполне чётко написал, что calling convention - cdecl, а на C# почему-то написал stdcall.
    Попробуй вот так:
    [DllImport("C:\\CMakeProject2.exe", CallingConvention = CallingConvention.Cdecl, EntryPoint = "test")]
        [SuppressUnmanagedCodeSecurity]
        private static extern void Test();

    Ну и библиотеки лучше таки именно в библиотеки собирать, а не в екзешники, и ложить рядом с твоим приложением, а не где-то в глобальной папке.
    Ответ написан
    3 комментария
  • Как из c++ выполнить python?

    Vindicar
    @Vindicar
    RTFM!
    Ну для начала нужно решить, нет ли возможности оставить две программы отдельно, связав их через стандартный ввод/вывод, файлы или сокеты? Пусть одна запускает другую просто как дочерний процесс, это проще всего.

    Если это категорически должна быть одна программа, то нужно решить, кто будет "главным".

    Если главным будет Питон, который должен вызывать код на C/C++ (оформленный в виде DLL), то может пригодиться модель ctypes. Альтернативно, можно написать модуль интерпретатора.

    Если главным будет C++, который должен выполнять код на питоне, то тут уже нужно читать про embedding python.
    Ответ написан
    Комментировать
  • Как сделать дерево объектов из массива?

    0xD34F
    @0xD34F Куратор тега JavaScript
    function createTreeFromArray(arr, key, parentKey) {
      const tree = Object.fromEntries(arr.map(n => [ n[key], { ...n } ]));
    
      return Object.fromEntries(Object.entries(tree).filter(([ , n ]) => {
        return !(tree[n[parentKey]] && ((tree[n[parentKey]].children ??= {})[n[key]] = n));
      }));
    }
    
    
    const tree = createTreeFromArray(arr, 'uid', 'parentUID');
    Ответ написан
    4 комментария
  • Как передать массив в функцию С++ ( пишет no matching function to call)?

    @res2001
    Developer, ex-admin
    Написал опус на вопрос, который вы удалили, хорошо сохранился в буфере обмена :-) а то было бы обидно.

    Ваш массив пожно просто привести к указателю, по старинке (int*)a или используя касты.

    Но у вас тут на самом деле 2 проблемы.
    Первая - обращение к элементам массива в average используя [i][j]. Вторая - VLA.
    По первой проблеме:
    В С/С++ оператор индексации (array[i]) выполняет следующее действие: *(array+i).
    Отсюда должно быть понятно, что раз array у вас это int*, то после array[i] вы получите int, от которого уже нельзя взять второй индекс, т.к. это просто 1 int, а не массив.

    Отсюда есть несколько выходов:
    1. дурацкий (самый долгий по исполнению и затратам памяти): использовать динамический массив массивов
    Выглядит примерно так:
    int **array = new int*[rowCount];
    for(int i=0; i < rowCount; ++i)
       array[i] = new int[colCount];

    Как видите array превратился в двойной указатель, теперь каждый элемент в первом измерении - это указатель на одномерный массив. Всего у вас получается rowCount + 1 выделений памяти. Не забудьте столько же раз вызвать оператор delete.
    В average теперь передавайте int** и у вас будет работать оператор [][], т.к. первая индексация уже будет возвращать int*.
    Не рекомендую использовать этотт способ.

    2. Вычислять индекс массива вручную (не использовать индексацию):
    *(array + i*colCount + j)
    Это такой хардкорный стиль. Но зато работает быстро и масштабируется на массивы любой размерности без особых проблем.

    3. использовать std::vector<std::vector<int>> - это то же самое, что и вариант 1, но закамуфлированный под вектор :-)

    Вторая проблема это VLA (Variable Length Array).
    Статические (автоматические) массивы в С++ вы можете определять, только константным размером (размером известным на этапе компиляции).
    У вас же размерность массива динамическая (вводится пользователем во время выполнения программы). Отсюда следует, что вы должны использовать динамические массивы, выделенные с помощью new.
    В стандарте С++ нет VLA. VLA есть только в Си и то начиная с С99.
    Ваша функция task3 компилируется, только потому что в gcc/clang по умолчанию включены расширения. В расширения входит так же и возможность использовать VLA. Если задать опциями более строгое соответствие стандарту С++, то функция не соберется.
    И кстати, например в микросовтовский компилятор VLA до сих пор не завезли.

    Но если уж у вас есть VLA, то вы можете преобразовывать указатель в VLA массив с помощью такой кучерявой конструкции:
    int (*array2)[colCount] = (int(*)[colCount]) array;

    В этом случае обращаться к элементам массива можно как обычно через двойную индексацию: array2[i][j]
    Когда-то делал тест на эту тему: https://ideone.com/4i6lRw
    Кстати, если в average сначала передать размерности, и последним параметром массив, то по идее массив можно сразу объявить двумерным, используя ранее переданные размерности:
    void average(int rowcount, int colcount, int aarray[rowCount][colCount])

    Это то же VLA.

    Вообще не рекомендую в С++ использовать VLA, т.к. программа становится не переносимой и зависимой от компилятора.
    Ответ написан
    4 комментария
  • Как передать массив в функцию С++ ( пишет no matching function to call)?

    Adamos
    @Adamos
    Используя Кресты, стоит использовать и их удобства.
    std::vector< std::vector< int > > a(rowCount, std::vector< int >(colCount, 0));
    void average (std::vector< std::vector< int > > &a){

    Так вы не нарветесь на промахи в индексах массива, например. Если умеючи.

    А в вашем коде int[][], конечно, не может самопроизвольно превратиться в int*
    Ответ написан
    2 комментария
  • Как разобраться с выводом valgrind?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    При попадании в блок:
    if (!result)
    память реально НЕ выделена и free от неё - это попытка освободить память по адресу NULL. Разумеется, это не будет работать.

    upd: Прочитал вопрос ещё раз внимательнее. Надо не забывать делать free в конечном месте использования этого result:

    result = get_next_line();<br>
    ...do_something_with_result...<br>
    free(result);


    Иначе да, при каждом вызове get_next_line будет выделяться новый блок на 2 байта.
    Ответ написан
    3 комментария
  • Как получить значения из массива объектов по id?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Сделать из teamNames объект, где ключами будут id:

    const teamNamesObj = Object.fromEntries(teamNames.map(n => [ n.id, n.name ]));

    Доставать из этого объекта имена:

    const eplWithNames = epl.map(n => ({ ...n, name: teamNamesObj[n.team_id] }));
    Ответ написан
    Комментировать
  • Как найти расстояние между двумя отрезками?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Задача разбивается на две более простые подзадачи.

    1) Проверить пересечение отрезков. Если пересекаются, то расстояние равно 0. Можно посчитать площади треугольников, образованных вершинами отрезков. Пересечение будет, если они имеют разный знак +-.

    2) если не пересекаются, то найти 4 расстояния, от каждого конца отрезка до другого отрезка. Это вреде обсуждалось тут ранее, поищи.
    Ответ написан
    Комментировать
  • Что передается с bind'ом?

    gbg
    @gbg
    Любые ответы на любые вопросы
    Acceptor::handleAccept - это нестатический метод класса Acceptor.

    У настатических методов первым параметром должен быть передан указатель на экземпляр класса. Когда вы вызываете методы класса напрямую, компилятор делает такую подстановку неявно. Когда вы это делаете через bind - нужно своими руками передать такой указатель, в данном случае - this.
    Ответ написан
    Комментировать
  • Как принять пробел в строку из пользовательского ввода?

    nowm
    @nowm
    В C++ есть getLine, и он читает всю строку:

    #include <string>
    #include <iostream>
    
    int main()
    {
       std::string words;
       
       std::cout << "Введите слова: ";
       std::getline(std::cin, words);
       
       std::cout << "Слова: " << words << "\n";
    }
    Ответ написан
    2 комментария
  • Почему берутся проблемы с совместимостью массивов и контейнеров?

    @Mercury13
    Программист на «си с крестами» и не только
    Учите матчасть!
    Версия для буфера памяти предполагает, что данные хранятся в непрерывном буфере nm×double (то есть длина mn, элемент double).
    Но vector<vector> — он НЕ непрерывный буфер.
    Есть непрерывный буфер n×vector<double> — центральный вектор. И каждая из n строчек по отдельности — непрерывный буфер m×double. Относительно друг друга в памяти они могут располагаться как угодно.

    Как исправить? — проще всего
    double s = 0;
    for (i...) {
      s += Sum(m, &a[i][0]);
    }

    Можно через шаблоны работать, но это уже сложнее и я сам не смогу это с листа написать, что уж говорить про первокура.
    Ответ написан
    Комментировать