Задать вопрос
Ответы пользователя по тегу C
  • Как реализовать кроссплатформенную поддержку Unicode в аргументах командной строки в C?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Соответственно, мне нужно конвертировать массив wchar_t в массив char перед шифрованием, а после дешифровки выполнять обратную конвертацию.

    Этот вывод не следует из исходных данных. Массив данных любого типа может быть проинтерпретирован как массив байтов, без какой бы то ни было конверсии. Т.е. исходные данные в любом формате можно зашифровать, а потом расшифровать обратно. Поэтому имеет смысл отделить преобразование форматов входных данных от шифрования/расшифровки.

    Я поменял сигнатуру функции main() на int main(int argc, wchar_t* argv[]) (пытался исправлять на wmain, но тогда ругается ld и сборка падает с ошибкой).

    То, что ты меняешь прототип main, никак не влияет на то, как она будет реально вызвана. В стандарте языка C написано, каким может быть прототип main: int main(void), int main(int argc, char *argv[]) или эквивалентным. Там же написано, что набор символов во время выполнения программы -- implementation defined, поэтому нет гарантии, что их можно обработать кросплатформенно.

    Для конвертации wchar_t* в char* я пробовал использовать функцию wcstombs, однако почему-то у меня она совершенно не работает (при попытке преобразовать строку, содержащую только латиницу, я получаю null).

    wcstombs не занимается выделением памяти, если ты "получаешь null" -- это происходит в каком-то другом месте. Ну и если ты это делаешь внутри main принимающего wchar_t* argv[], то твой код интерпретирует строку char как строку wchar_t, что добавляет хаоса.
    Ответ написан
  • Скомпилированный в GCC exe файл вылетает досрочно?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Но в режиме отладки всё, как я уже писал выше, работает.

    Да не, это только видимость. Смотри:

    $ gcc -std=c99 -O2 -g3 -fsanitize=address main.c acp.c md5.c -o main
    $ ./main
    Base64('Hello') = "SGVsbG8="
    MD5('Hello') = "8b1a9953c4611296a827abf8c47804d7"
    =================================================================
    ==1045705==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x604000000071 at pc 0x7fb0d46486f8 bp 0x7ffd0affb580 sp 0x7ffd0affad30
    WRITE of size 33 at 0x604000000071 thread T0
        #0 0x7fb0d46486f7 in __interceptor_strcat ../../../../src/libsanitizer/asan/asan_interceptors.cpp:377
        #1 0x564b2388c0de in prepareKeys /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/acp.c:263
        #2 0x564b2388cac4 in acraw /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/acp.c:319
        #3 0x564b2388d8c2 in acraws /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/acp.c:401
        #4 0x564b2388d8c2 in acraws_basic /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/acp.c:409
        #5 0x564b2388a62e in testSimpleEncryption /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/main.c:20
        #6 0x564b2388a368 in main /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/main.c:111
        #7 0x7fb0d44461c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
        #8 0x7fb0d4446284 in __libc_start_main_impl ../csu/libc-start.c:360
        #9 0x564b2388a440 in _start (/home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/main+0x3440)
    
    0x604000000071 is located 0 bytes to the right of 33-byte region [0x604000000050,0x604000000071)
    allocated by thread T0 here:
        #0 0x7fb0d46b89cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
        #1 0x564b2388fee7 in md5StringHash /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/md5.c:227
    Ответ написан
  • Может ли язык Си работать на условной stack-based машине?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Может ли язык Си работать на условной стековой машине? … В виде стековой машины я имею в виду условную машину Тьюринга

    Есть такая штука, тезис Чёрча — Тьюринга, которая говорит, что любой алгоритм может быть реализован машиной Тьюринга.

    Будут ли какие-то проблемы для генерации кода из Си в ассемблер для подобной машины?

    Для этого надо уточнить, что такое "проблемы".
    Ответ написан
  • Что не так с Futex?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    почему такая ошибка со своим mutex

    потому что pthread_t шире чем int owner, и как следствие этот тест не работает.
    Ответ написан
  • Почему невозможно получить доступ к каталогу?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему ls не работает

    потому что main в процессе демонизации меняет текущий каталог на /. Если запускать его с полным путём (например ./main `pwd`/mntpoint) -- то становится лучше. Но всё ещё не работает, потому что при использовании обработчиком запроса на доступ к каталогу этого же самого каталога происходит бесконечная рекурсия и исходный запрос не завершается.
    Лучше спроси, как я это понял.
    Ответ написан
  • С чего начать, чтобы написать свою библиотеку по загрузке бинарника в микроконтроллер?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    У твоей задачи есть как минимум два решения. Одно, попроще: взять готовую программу прошивки, посмотреть, как она работает, написать библиотеку реализующую то же самое. Другое, посложнее: начать со спецификации контроллера который ты собираешься прошивать и раскручивать зависимости с той стороны. Поскольку ни то, ни другое решение сами по себе большого смысла не имеют (потому что есть уже программы для прошивки), тебе надо решить, чего ты сам хочешь получить от этого упражнения.

    Есть, может, какие-то специальные книги по этой теме?

    Спецификации на контроллер, а недостаток большой картины можно покрыть википедией и всяким osdev.org
    Ответ написан
    Комментировать
  • Возможно ли как-то использовать обычную функцию заместо макро-функции?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    #define BIT_SET(port, bit) (port |= (1 << bit))
    
    int main(void)
    {
        BIT_SET(PORTB, PORTB0);
    }


    вот такой вариант, с макро-функцией, работает, так как это просто текстовая замена

    Он работает, потому что с таким определением BIT_SET PORTB не может быть определён просто как 0x04. Потому что просто текстовая замена 0x04 |= 1 << 0 не имеет смысла. Он определён как volatile ссылка на память с адресом 0x04. Когда ты научишься передавать ссылку на такую память в функцию, функция тоже начнёт работать.
    Ответ написан
    3 комментария
  • Почему библиотека не ставится?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Пытаюсь поставить библиотеку, не получается
    почему?
    file INSTALL cannot find
    "/home/durachok/HTTPParser/build/_deps/ethernet-src/include/Ethernet.h": No
    such file or directory.


    Потому что здесь написана какая-то фигня, ссылающаяся на несуществующий файл.
    Ответ написан
    Комментировать
  • Не могу понять почему не работает USER тред?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    почему не работает USER тред?

    Потому что, опять, ты вызываешь makecontext не задав uc_link. thread_func1 отрабатывает, а дальше гонка между вызовом thread_func2 из monitor_thread и завершением программы из-за возврата из функции контекста в контексте созданном с uc_link == NULL.

    Но и без этого код выглядит загадочно. Непонятно зачем мешать в одну кучу контексты и clone. Непонятно зачем дублировать указатель на функцию в Thread::func и в Thread::context. Непонятно зачем контексты, если schedule их не использует. Непонятно, зачем monitor_thread занимается активным ожиданием Thread::active. Непонятно, зачем функции потоков лезут в потроха Thread. Короче, этому коду не хватает идеи.
    Ответ написан
  • Почему не печатается?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему не печатается "custom thread completed"

    Потому что thread->context.uc_link = NULL; в строке 27, а, согласно man swapcontext:
    If the successor context pointer is NULL, the thread exits.


    Исправить можно, например, так:
    int custom_thread_create(custom_thread *thread, ucontext_t *link, void (*start_routine)(void*), void *arg) {
        …
        thread->context.uc_link = link;
        …
    }
    …
        ucontext_t main_context;
        getcontext(&main_context);
    
        if (custom_thread_create(&thread, &main_context, print_message, (void*)message) == 0) {
    …
    Ответ написан
  • Где найти такую CLI?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Хочется как-то отойти от указания всех параметров а считать что есть некий контекст.

    Я вот так делаю в подобных случаях. Т.е. загружаю конфигурацию из конфиг-файла если он есть, а потом поверх неё -- из параметров командной строки. Среди которых могут быть другие конфиг-файлы.
    Ответ написан
    Комментировать
  • Как скомпилировать код C в .ko?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Ответ написан
    Комментировать
  • Пробую собрать bmminer-cgminer492, ошибка при сборке. Каких зависимостей не хватает?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    получаю следующую ошибку

    судя по тексту ошибок, всего хватает, но ошибки в коде. Я бы в cgminer.c добавил #include <inttypes.h>
    Ответ написан
    Комментировать
  • Почему waitpid() возвращает ошибку?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему waitpid возращает такую ошибку?
    waitpid: No child processes

    Потому что он вызывается как в родительском, так и в дочернем процессе. В родительском процессе он работает успешно, а у дочернего процесса waitpid вызывается с pid == 0, а такого процесса точно нет.
    Ответ написан
  • Avr-gcc почему не работает обращение к полям структуры по индексу в цикле?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    если просто вручную написать обращение по индексу, то всё работает корректно
    Почему такое может быть

    Если посмотреть в сгенерированный код (я компилировал командой
    avr-gcc -mmcu=atmega2560 -DF_CPU=8000000 -fverbose-asm -S test.c
    ), то можно увидеть, что он не обращается к массиву power_5v, а все константы просто подставлены как непосредственные значения в инструкции. Я думаю, что по этой причине.

    как это исправить

    Нужны детали: версия компилятора, опции компиляции.
    Ответ написан
    Комментировать
  • Почему нет ошибок, но ничего не выводит?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    struct message{
        int id;
        char* data;
    };
    …
    send(fds[i].fd, &msg, sizeof(msg), 0)

    Этот send отправляет клиенту не данные, а указатель. Указатель на данные, которых у клиента нет.

    // Add new socket to poll array
                fds[nfds].fd = new_socket;
                fds[nfds].events = POLLIN;
                nfds++;
            }
     
            // Check for data from clients
            for (int i = 1; i < nfds; i++) {
                if (fds[i].revents & POLLIN) {


    Здесь ты добавил сокет в массив дескрипторов полл и сразу проверяешь, не установлен ли у него revents. Но это поле в этот момент не инициализировано. Мало того, ты просишь ожидать POLLIN, но клиент никогда ничего не отправляет серверу, поэтому и сервер не дождавшись POLLIN никогда ничего не отправляет клиенту.

    struct pollfd fds[1];
        fds[0].fd = sock;
        fds[0].events = POLLOUT;
        if (poll(fds, 1, -1) <= 0) {
            perror("poll failed");
            exit(EXIT_FAILURE);
        }
        if (!(fds[0].revents & POLLOUT)) {
            perror("connect failed");
            exit(EXIT_FAILURE);
        }
    
        // Receive message from server
        while ((valread = read(sock, &msg, sizeof(msg))) == -1 && errno == EAGAIN);


    Здесь ты ждёшь до POLLOUT, но после этого начинаешь читать. Это малость нелогично, потому что наличие данных для чтения показывается флагом POLLIN. POLLOUT же на свежеустановленном соединении есть сразу, поэтому чтение тупо вертится в цикле while пока не прийдут данные.

    как это можно попробовать подебажить понять что не так, что происходит

    Можно тупо повставлять печать в ключевые места, что да, соединение установлено, соединение принято, полл завершился успехом, данные отправлены, данные приняты.
    Ответ написан
    Комментировать
  • STM32 ловит HardFault_Handler на операторе += как починить?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Вопрос номер раз: как такое вообще произошло?

    Насколько я понимаю STM32F207xx не поддерживает инструкцию uxtah, потому что это инструкция Thumb2 не реализованная в CortexM3.

    Вопрос номер два: как такое фиксить?

    Подозреваю, что ключом -march=, вероятно -march=armv6.
    Ответ написан
    1 комментарий
  • Почему он пишет что оно не shared? OPENMP?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    На что он ругается?

    На то, что ты в прагме сказал, что будешь редуцировать в norm_b_square, а в цикле работаешь с *norm_b_square. А если ты имел в виду одноимённый norm_b_square из функции main, то нет, нельзя так сослаться на автоматическую переменную из другой функции.

    Вся эта задумка сделать автоматическую переменную в одной функции shared а потом в другой функции с ней работать по указателю нерабочая. Либо работай с ней в той же самой функции, либо выноси её за пределы функции.
    Ответ написан
    Комментировать
  • Почему поведение fscanf ( stdin, "%c", &c ) различается при чтении EOF в msvc и gcc?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    После ввода Ctrl+Z и нажатия Enter, если я правильно понимаю, в потоке появляется только EOF и символ новой строки.

    Это странное заявление. Потому что "конец файла" стандартом С (конкретно, С99) определяется так: end-of-file, that is, no more input from a stream. Это значит, что ни EOF как символ, ни что бы то ни было после конца файла прочитано быть не может. Если чтение работает (т.е. функции чтения не возвращают ошибок, либо ошибки не указывают на конец файла), то конец файла не достигнут.

    Сравните поведение этих программ при обычном запуске и при запуске с перенаправлением ввода из пустого файла. Если есть разница, то это может указывать на то, что нажатие Ctrl+Z в cmd не вызывает закрытие потока ввода для процесса.
    Ответ написан
  • Почему strcat перезаписывает переменные?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    почему так происходит?

    Потому что str и word -- это переменные размером в один символ, а в строке char delimeters[6] = " .,!?;" отсутствует 0-терминатор. Поэтому
    - scanf("%s", &str); вылезет за пределы str если ввести здесь что угодно.
    - strcat(&word, &c); вылезет за пределы word если в c будет не пустая строка. А в c будет неизвестно что, потому что c = getchar() не добавляет в эту строку 0-терминатор.
    - strchr(delimeters, c); может вернуть что угодно, если c не входит в delimiters.
    Ответ написан
    8 комментариев