• Сmake не подключаеться библиотека curses,что делать?

    @res2001
    Developer, ex-admin
    Ошибка у вас не про библиотеку, а про
    add_executable(ctest ${SOURCES})
    Переменная SOURCES не определена там где она используется. Поэтому ctest получается без исходников - собирать нечего.

    Вообще обычно подключаю библиотеки через find_package или pkg_check_modules, но для этого надо использовать какую-то среду с пакетным менеджером и возможно поддержкой pkgconfig. Под виндой можно использовать msys2+mingw например - там все это есть. Или vcpkg для MSVS (или что там сейчас актуальное, не отслеживаю).
    Ваш вариант подключения то же должен работать, но надо еще указать путь к заголовочным файлам, чтоб было совсем красиво. Подобный способ не переносим, стоит поискать альтернативу.
    Ответ написан
    5 комментариев
  • Как настроить CMake в Clion для stm32 для подключения библиотек?

    @res2001
    Developer, ex-admin
    Попробуйте в include_directories() указывать полные пути. Стандартная переменная cmake ${CMAKE_CURRENT_SOURCE_DIR} содержит путь где лежит текущий файл cmakelists.txt, ее можно использовать для генерации полного пути.
    Обычно, если в проекте используется иерархия каталогов, то в каждом каталоге с исходниками лежит свой собственный cmakelists, а подключается он к нижележащему через add_subdirectory(). Собирайте в каждом каталоге свою цель (статическую библиотеку), потом эти цели указывайте в зависимостях для основной цели.
    Ответ написан
    Комментировать
  • Код работает по другому из-за защиты сервера?

    @res2001
    Developer, ex-admin
    Если очень хочется делать это в онлайн, то пользуйтесь другими онлайн-компиляторами.
    https://godbolt.org/ например. Sololearn выглядит в этом плане довольно скудно.
    Но тем не менее первый вариант выдал правильный результат.
    Можете собирать на своем компе ваши примеры.
    Ответ написан
  • Правильно ли я описал передачу параметров из функции С++?

    @res2001
    Developer, ex-admin
    Код надо вставлять текстом в соответствующем теге, есть кнопка в панельке.
    Передаешь правильно. Что есть сомнения? Просто запусти программу для проверки с разными значениями.
    Т.к. это С++ то можно использовать ссылки вместо указателей.
    Ответ написан
    Комментировать
  • В чем разница записи массива через указатели?

    @res2001
    Developer, ex-admin
    Приоритет операции * выше, чем у -
    Ответ написан
    Комментировать
  • SSH/Ftp как сетевой диск (с буквой) под Win11 как?

    @res2001
    Developer, ex-admin
    Есть такая штука sshfs - то что вам надо. Есть реализация и для винды, гуглите.
    Ответ написан
    Комментировать
  • Как правильно вернуть параметр и передать в main C++?

    @res2001
    Developer, ex-admin
    static void createCharacter(UserCharacter& character) {
    ...
    /* Возврат значений происходит через ссылку, переданную в параметре. 
    В return ничего возвращать не нужно. 
    Создавать другие объекты UserCharacter не нужно. */
    character.x = 10;
    character.y = 10;
    ...
    }
    
    int main() {
     UserCharacter character;
     ...
     createCharacter(character);
      ...
    }
    Ответ написан
    1 комментарий
  • Как происходит динамическое выделение памяти в С++?

    @res2001
    Developer, ex-admin
    Что подразумевается под динамикой?

    Выделение памяти в куче.

    Память может быть выделена:
    1. на стеке - автоматическая память
    2. в сегментах bss, data, rodata - статическая
    3. в куче - динамическая

    С точки зрения памяти - это все просто память процесса (некоторые диапазоны адресов в доступном адресном пространстве процесса). Но выделяется и освобождается она в разное время жизни процесса.

    Стек выделяется при старте потока (в любом процессе есть хотя бы один поток выполнения), имеет фиксированный
    размер. Освобождается стек при завершении потока. Фактически при объявлении переменной на стеке происходит просто увеличение (уменьшение) указателя стека на размер переменной, при удалении - обратный процесс. Поэтому выделение памяти на стеке очень быстрое. Переменные "живут" на стеке пока действует их область видимости, после выхода из области видимости - уничтожаются.

    Статические сегменты памяти выделяются и инициализируются при загрузке исполняемого файла программы в память еще до старта любого кода программы. Сегменты предназначены для хранения статических инициализированных/не инициализированных переменных и констант. Фактически описание этих сегментов содержится в исполняемом файле и подготавливается компилятором. Загрузчик ОС, читает эти сегменты из исполняемого файла в память. Названия сегментов (bss, data, rodata) имеют смысл только для исполняемого файла, после загрузки сегментов в память есть только адреса начала сегментов и их размер (и другие свойства страниц памяти сегментов).

    Куча. Память в куче выделяется по явному запросу программы (new) и уничтожается так же (delete). Не смотря на всю простоту интерфейса выделения/освобождения памяти операции эти довольно затратны (по процессорному времени) и под капотом может происходить много телодвижений, поэтому не следует выделять/освобождать память в куче на каждый int или еще хуже char. Для большинства программ эти затраты не критичны, но в некоторых случаях могут стать узким местом вашей программы.
    Ответ написан
    1 комментарий
  • Следую туториалу по тому как использовать vcpkg в проектах CMake, но выдается ошибка, может я что-то не сделала?

    @res2001
    Developer, ex-admin
    Судя по ошибке, cmake пытается использовать генератор "NMake Makefiles". nmake - это такой куцый вариант make от микрософт, идет в составе MSVS. Но MSVS у вас, похоже, не установлен, вот cmake и не может его найти.
    Обычно генератор задается опцией -G при вызове cmake.
    Список поддерживаемых генераторов смотрите: cmake --help
    Но это не значит, что все они будут работать в вашей конфигурации, т.к. все они требуют дополнительного ПО.

    Под виндой, обычно ставят MSVS или Build Tools и выбирают соответствующий генератор в cmake (или возможно cmake находит сам подходящий генератор).
    Альтернативные варианты:
    msys2+mingw - генератор MSYS Makefiles или MinGW Makefiles
    msys2+mingw+ninja - генератор Ninja
    mingw можно заменить на clang.

    Смысл в том, что VS Code - это грубо говоря текстовый редактор адаптированный для написания программ.
    cmake - это система сборки.
    Но ничего из этого самостоятельно компилировать программы не умеет - они используют какой-то компилятор, который надо установить в систему. Какой именно - выбирать вам.
    MSVS, в отличие от VS Code, это IDE со встроенным компилятором - и там уже полный фарш, думать как собрать программу не надо.
    Но разобраться в этой кухне стоит, раз уж вы изучаете С/С++.
    Ответ написан
  • Что и почему лучше подключить в C++? math.h или cmath? stdio.h или cstdio?

    @res2001
    Developer, ex-admin
    В С++ используют вариант где не указывают расширение .h в include. С расширением это для исходников на Си.
    Впрочем, как вы верно заметили, в плюсах это то же работает. Обычно внутри <cxxxx> просто делается #include <xxxx.h>
    Ответ написан
    Комментировать
  • Как подключить файл с помощью макроса к другому файлу?

    @res2001
    Developer, ex-admin
    У вас в вопросе 2 варианта main.
    В первом будет ошибка, во втором нет при сборке командой:
    gcc main.c function1.c

    Чтоб в первом случае не было ошибки нужно собирать командой:
    gcc main.c
    т.к. function1.c включается в main.c с помощью include и его не нужно повторно давать компилятору.
    Эта команда для сборки второго варианта main не подойдет.
    Ответ написан
  • Почему при работе батника не отображается результат поиска файла?

    @res2001
    Developer, ex-admin
    Попробуйте такой вариант цикла в searchdone: for /f "usebackq delims=" %%I in ("%tempfile%")

    Согласен с pumpkinm, на счет выполнения вложенного cmd. Возможна ситуация, что на момент выполнения чтения файла с результатом, этот файл все еще захвачен процессом вложенного cmd и type не может его прочитать.
    Ответ написан
  • Не работает case в switch. Как решить проблему?

    @res2001
    Developer, ex-admin
    Блоки case в операторе switch это просто аналог меток для goto. Соответственно после перехода на какой-то case выполнение программы продолжается по всем строкам кода подряд. И если вы не предусмотрели явный выход из блока case (с помощью break или return), то выполнение продолжится и в следующем case и т.д.

    Современные компиляторы умеют выдавать ошибки или предупреждения для таких случаев, т.к. очень часто в коде действительно присутствует ошибка - пропуск оператора break или return (как у вас). В gcc для этого служит опция -Wimplicit-fallthrough. Иногда проваливание в следующий case бывает полезно и используется на практике программистами, тогда (при использовании опции -Wimplicit-fallthrough) надо явно указать на это компилятору. В документации gcc в описании этой опции указано как это сделать.

    Вообще рекомендую ужесточать проверки компилятора, как минимум с помощью стандартных опций: -Wall -Wextra.
    А так же указывать какому стандарту языка надо придерживаться компилятору: -std=c++17 или -std=gnuc++17
    Можно добавить и опцию: -pedantic
    По умолчанию многие полезные предупреждения отключены.
    Многие предупреждения можно перевести в ошибку или игнорировать.
    Есть и другие полезные проверки, которые может делать компилятор, которые не входят в -Wall -Wextra. Но для начала используйте хотя бы их.

    Описание опций предупреждений gcc смотри тут: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
    Ответ написан
    Комментировать
  • Как хранятся многомерные массивы в памяти?

    @res2001
    Developer, ex-admin
    Многомерные массивы можно задавать несколькими способами:
    int arr1[2][3];
    int (*arr2)[3] = new int[2][3];
    int *arr3 = new int[2*3];
    int **arr4 = new int*[2];
    arr4[0] = new int[3];
    arr4[1] = new int[3];
    
    // Следующие утверждения верны:
    static_assert(sizeof(arr1) == (sizeof(int)*2*3));
    static_assert(sizeof(arr2) == sizeof(int(*)[3]));
    static_assert(sizeof(arr3) == sizeof(int*));
    static_assert(sizeof(arr4) == sizeof(int**));
    
    static_assert(sizeof(arr1[0]) == (sizeof(int)*3));
    static_assert(sizeof(arr2[0]) == (sizeof(int)*3));
    static_assert(sizeof(arr3[0]) == sizeof(int));
    static_assert(sizeof(arr4[0]) == sizeof(int*));

    В 1-3 варианте данные массива хранятся последовательно друг за другом по строкам. 4 вариант - это "массив массивов" (его могут называть и по другому), тут требуется отдельный массив указателей, данные строк могут хранится в разных местах памяти.
    Обращаться к элементам arr1, arr2 и arr4 можно с помощью индексации: arr1[i][j] и это будет работать, но по разному для arr1/2 и arr4.
    arr3 это по сути одномерный массив. То что он двумерный знаете только вы как программист. Поэтому через индексацию можно обращаться только к первой размерности. Чтоб включить и вторую размерность потребуется ее явно посчитать. Например для элемента arr2[1][2]:
    *(arr2 + 1 * 3 + 2);
    // или то же самое
    arr2[1*3 + 2];


    С точки зрения производительности 4 вариант самый плохой, т.к. для обращения к элементу требуется два чтения памяти, а так же из-за того что каждая строка хранится отдельно от других в памяти, то кэш процессора будет использоваться менее эффективно, чем для остальных вариантов. Кроме того тут используется дополнительный массив указателей (первая размерность).
    Не смотря на то что 3 вариант кажется довольно многословным (особенно если константы заменить на осмысленные имена переменных), но на производительности это никак не сказывается, т.к. по сути те же самые вычисления индекса делаются и для arr1/2, только для них это делает компилятор сам неявно.
    Ответ написан
    Комментировать
  • Не могу понять почему не работает USER тред?

    @res2001
    Developer, ex-admin
    Видимо потому что main заканчивается и программа завершается вместе со всеми потоками.

    Вообще не понятно, что ты этим хотел сказать. Где вызов swapcontext? Без него стеки псевдопотоков не используются и переключение контекстов не происходит. Зачем они тогда тут нужны?
    В прошлом варианте с таймером, по крайней мере, была идея и было понятно, чего ты хотел добиться. Хоть оно и не работало.
    Ответ написан
  • Как отключить TlS в Windows?

    @res2001
    Developer, ex-admin
    Отключить TLS в винде можно настройками реестра. В свое время, когда нашли уязвимость в SSL3.0, все ринулись переходить на TLS с помощью запрета SSL. Аналогично можно запретить и TLS.
    Вот статья с того времени, там найдете указание где это отключается в реестре: https://www.atraining.ru/beast-move-from-ssl-to-tls/
    Описание самих ключей реестра ищите у микрософта.

    Но это влияет на софт, который использует механизмы ОС для шифрования трафика. Например это работало для RDP или для Internet Explorer.
    Если приложение использует например openssl для шифрования, то этот вариант не будет работать. Тут надо искать какой-то вариант запрета через openssl. Есть и другие библиотеки, реализующие шифрование.
    Ответ написан
    Комментировать
  • Как решить проблему с Segmentation fault?

    @res2001
    Developer, ex-admin
    Ошибка выполнения stat для файла: No such file or directory

    Потому что:
    strcpy(filename, "mntEntry->mnt_dir");
    Вы записываете в filename строку "mntEntry->mnt_dir", а не каталог.
    Добавить затем слэш в конец можно так: strcat(filename, "/");
    Или вручную:
    size_t len = strlen(filename);
    filename[len] = '/';
    filename[len + 1] = '\0';

    В целом ничего предосудительного не вижу, вы даже проверяете ошибки, возвращаемые системными функциями - многие этим пренебрегают.

    Есть еще момент. В линукс есть константа PATH_MAX она задает максимальный размер пути к файлу. Рекомендую ваши буфера для хранения путей делать размером PATH_MAX.
    Ответ написан
  • Шифрует ли SSH web-трафик при подключении к http://localhost в браузере?

    @res2001
    Developer, ex-admin
    Данные от ssh клиента до ssh сервера идут в шифрованном виде.
    От браузера до ssh клиента и от ssh сервера до веб сервера идет обычный HTTP или HTTPS.
    Ответ написан
    Комментировать
  • Почему после ассемблера учить Си легче?

    @res2001
    Developer, ex-admin
    Утверждение пожалуй верно.

    Лично на мой взгляд это из-за того, что и в ассемблере и в Си есть указатели. Причем в ассемблере ничего кроме указателей для работы с памятью нет (имею ввиду именно оперативную память, а не регистровую или ПЗУ) и вам волей-неволей на ассемблере придется понять, что это такое и как реально работает память в компе. И с этими знаниями очень легко уже понять указатели в Си, т.к. это суть одно и то же, только синтаксис разный.

    В Си же есть альтернатива - можно попытаться использовать только автоматические или глобальные переменные и не использовать указатели. Но более-менее большой проект с такими самоограничениями не возможен, на мой взгляд. Из-за наличия альтернативы использования памяти, тема указателей (и ручного управления памятью) в Си кажется сложной и многих отпугивает.
    Но в реальности, понять Си гораздо проще, чем ассемблер. Так что не уверен, стоит ли подобная овчинка выделки.

    Если вам для чего-то нужен ассемблер, то видимо, стоит с ним разобраться. Но разбираться с ассемблером для изучения Си - это какой-то садомазохизм. Си довольно простой ЯП. Ассемблер сам по себе то же не сложен, но что бы на нем что-то писать нужно хорошо знать и понимать архитектуру конкретного процессора.

    У издательства ДМК пресс есть книжки по ассемблеру (в т.ч. по АРМ) и по архитектуре компьютеров, можете посмотреть у них на сайте, там же можно и купить. Что плохо, они не делают скидку на электронные книги, как многие другие.
    Изучать нужно ассемблер под ту платформу, на которой вы сможете писать тестовые программы. Обычно это х86, но при наличии, например, малинки или апельсинки можно и АРМ попробовать.
    Конечно можно и эмулятором воспользоваться, но это лишние проблемы. А может и не лишние - если уж вы хотите ассемблер, то это может пригодиться.
    Ответ написан
    Комментировать
  • Если в Linux операции с файлами в пределах потока блокирующие, то как тогда работают БД?

    @res2001
    Developer, ex-admin
    Мне кажется с блокировками вы несколько путаетесь. В данном случае могут быть заблокированы 2 объекта на одной файловой операции:
    1. поток, использующий синхронную операцию чтения/записи в файл
    2. файл открытый для монопольного доступа

    Думаю ваш вопрос не связан с п.1, т.к. это больше про параллельное программирование, а не про файлы и БД.
    Файловые операции легко могут не блокировать поток - асинхронный ввод/вывод.
    Файл можно открыть с монопольным доступом и с общим доступом. В общем доступе этот же файл может открыть и другое приложение одновременно с вашим.
    При общем доступе вы можете блокировать какую-то область файла и работать с этой областью "монопольно".
    БД открывают свои файлы в монопольном режиме.
    В разных потоках одного приложения вы можете открыть файл один раз и работать с одним и тем же дескриптором файлов из разных потоков. Но это может создать кучу проблем с целостностью структуры файла, если много потоков будут не согласованно писать в файл.
    Файловые операции ОЧЕНЬ медленные. Поэтому все нормальные базы данных работают через свой собственный кэш. Поэтому там, обычно нет кучи потоков, которые лопатят файл БД. Движок SQL берет данные из кэша, есть некий "менеджер кэша" - отдельный поток, которому движок дает запрос на данные, если данных в кэше прямо сейчас нет, то менеджер кэша читает данные из файла в кэш и отдает эти данные запрашиваемому потоку. Чтение файла наверняка то же идет не на прямую, а запросы на чтение ставятся в очередь и возможно какой-то другой поток (или тот же менджер кэша) по очереди читает необходимые данные. Аналогично и с записью - через кэш и последующую очередь на запись.
    Если запустить MS Sql Server с настройками по умолчанию с достаточно большой по объему базой он довольно быстро отожрет в компе вообще всю свободную память (конечно, если БД меньше, чем объем ОЗУ, то всю память не отожрет). Не то что бы ему очень нужно прямо сейчас вот столько памяти (он может в это время вообще простаивать), просто он начитал данные в кэш.
    Как-то так я это вижу.
    Ответ написан
    Комментировать