Ответы пользователя по тегу C
  • Как скомпилировать код 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 комментариев
  • Почему компиляторы не используют инструкции повторения REP movs?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему компиляторы не используют инструкции повторения REP movs?

    чего это "не используют"? Используют.

    Она должна быть в миллиард раз быстрее

    Инструкция которую не нужно читать из памяти, но которая сама лезет в память дважды на каждом цикле своего выполнения не может быть "в миллиард раз быстрее" других реализаций той же логики.
    Ответ написан
    Комментировать
  • Почему ptrace если не через execl не работает?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Потому что PTRACE_TRACEME не останавливает вызывающий процесс, а значит у родителя нет возможности заказать остановку по системному вызову. Останавливают трассируемый процесс только сигналы и явно запрошенные трассировщиком события.
    В частности, вызов execve трассируемым процессом вызывает отправку ему сигнала SIGTRAP.
    Можно вставить перед 20й строкой какой-нибудь asm volatile ("int3"); и это тоже вызовет доставку сигнала, останов и трассировку последующих вызовов write.
    Ответ написан
  • Как сделать вызов функции из терминала чтобы обработчик динамически искал и вызывал функцию?

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

    У этой задачи есть два больших класса решений -- системно-независимые и системно-зависимые, в зависимости от дополнительных условий. Для начала надо ответить на вопрос "где ищет". Если ответ на этот вопрос -- "в твоём приложении", а набор функций фиксированный, то можно построить отображение "имя функции" -> "адрес функции" с использованием какого-нибудь массива или хеш-таблицы и искать с его помощью.
    Если набор функций не фиксирован во время сборки приложения, или искать надо за пределами приложения, нужно ответить ещё на один вопрос: "знают ли функции о том, что их будут выполнять или нет". Если знают -- опять же построить отображение "имя функции" -> "адрес функции" и каким-нибудь образом сделать его доступным приложению. Если речь идёт о вызове произвольных заранее неизвестных функций, остаётся вариант с динамической загрузкой и поиском имён -- dlopen/dlsym или LoadLibrary/GetProcAddress для венды.
    Ответ написан
    Комментировать
  • Как правильно посчитать время выполнения fread/fwrite (gcc)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как правильно посчитать время выполнения fread/fwrite
    Нужно посчитать время чтения и время записи одинакого размера блока данных на диск.
    Причем, время момента, когда данные окажутся на диске

    fread/fwrite -- плохой выбор для этого, потому что это функции библиотеки C, т.е. между ними и ядром ОС ещё один слой абстракции.

    Я правильно понимаю, что fclose(f) закрывает файловый дескриптор f после того как данные записаны на диск?

    Неа. Тот кто читает маны должен приучаться делать это до конца. В случае fclose -> fflush там написано следующее:
    Note that fflush() flushes only the user-space buffers provided
    by the C library.  To ensure that the data is physically stored
    on disk the kernel buffers must be flushed too…


    нужна функция get_time_func()

    Стандартный способ -- clock_gettime, в качестве clockid думаю подойдёт CLOCK_MONOTONIC_RAW.
    Ответ написан
  • Как работает %[^\n]s?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Верно ли я понимаю, что первый scanf читает поток и останавливается на \n , после чего каждый последующий вызов scanf начинает чтение с этого же символа (\n) и, следовательно, моментально останавливается

    Понимаешь верно. Вдобавок форматная строка %[^\n]s содержит символ s который никогда не заматчится, потому что %[^\n] останавливается на символе '\n'. Логично было бы заменить её на %[^\n]%*c чтобы работало так, как было задумано.
    Ответ написан
    3 комментария
  • Почему scanf считывает значение только первой переменной?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    while (scanf("%f %f %f", &a, &b, &c) != 1 || ...

    В приведённом коде нет определений a, b и c. Они должны иметь тип float, чтобы формат %f scanf работал правильно.

    если сначала ввести 1 2 3, то приложение выведет "Ошибка. Введите снова: "
    как это исправить?

    scanf возвращает число успешно отсканированных полей, возвращаемое scanf значение надо сравнивать с 3 в условии цикла.
    Ответ написан
    Комментировать
  • Как выводить русские символы в си?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    как это работает

    Поскольку русский -- не часть ASCII, работает это по-разному в зависимости от кодировки. Если предположить, что исходник в UTF-8, то русские символы закодированы двумя байтами, а %c выводит только один. Если на одном выведенном байте остановиться -- получится фигня с вопросом. Но если вывести подряд все байты многобайтового символа -- получится этот символ.

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

    вариантов несколько. Самый простой -- выводить строки целиком. Если надо выводить посимвольно, можно узнавать количество байт в представлении одного символа функцией mblen, типа того:
    #include <locale.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main() {
      char *a = "Привет, мир";
      int s;
      setlocale(LC_ALL, "");
      for (; *a != '\0'; a+=s) {
        s = mblen(a, strlen(a));
        printf("%.*s-", s, a);
        }
        return 0;
    }

    Здесь setlocale нужен для того, чтобы mblen понял, в какой кодировке символы на входе. Локаль в момент выполнения должна быть совместимой с кодировкой исходника в момент компиляции, если это условие не выполняется, работать будет неправильно.

    Ещё вариант -- работать не с многобайтовой кодировкой а с wchar_t:
    #include <locale.h>
    #include <stdio.h>
    #include <stddef.h>
    
    int main() {
      wchar_t *a = L"Привет, мир";
      setlocale(LC_ALL, "");
      for (; *a != '\0'; a++) {
        printf("%lc-", *a);
        }
        return 0;
    }

    Здесь setlocale нужен для другого: он говорит внутренностям printf в какую локаль выполняется вывод чтобы в неё конвертировать wchar_t. Если локаль во время выполнения не будет соответствовать кодировке исходника, код всё равно будет работать.
    Ответ написан
    2 комментария
  • Bsd-socket. Почему бесконечное чтение при http запросе?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    При повторной итерации read, по идее, должен вернуть 0, так как все прочитано

    Неа, не так это работает. 0 из read возвращается в одном единственном случае: если та сторона закрыла сокет на передачу и все посланные ею данные получены. В противном случае (сокет не закрыт) поведение зависит от настроек сокета: синхронный сокет при попытке чтения может заблокироваться в функции read или вернуть из неё -1 (и установить errno, например, в EINTR). Асинхронный сокет вернёт из read -1 и установит errno в EAGAIN или EWOULDBLOCK.
    Ваш HTTP-сервер наверняка оставляет соединение открытым после того как прислал ответ на первый запрос, это можно понять по наличию заголовка Connection: Keep-Alive или отсутствию заголовка Connection: close в его ответе если это HTTP/1.1. Его можно попросить закрыть соединение после ответа, послав запрос с заголовком Connection: close или можно избежать блокировки в read прочитав только данные ответа размер которых прислан в заголовке ответа Content-Length.
    Ответ написан
    2 комментария
  • Почему вместо строки появляется мусор?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему вместо строки появляется мусор?
    size_t xpath_formatted_size = vsnprintf(NULL, 0, xpath, arguments);
      char* xpath_formatted = malloc(xpath_formatted_size);
      vsnprintf(xpath_formatted, xpath_formatted_size, xpath, arguments);


    Потому что 1) результат возвращаемый vsnprintf не включает конечный 0, а вот аргумент vsnprintf обозначающий размер буфера должен включать место для конечного 0. И 2) вызов vsnprintf(…, arguments) меняет arguments.

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

    Как-то так:
    char* xpath_format(const char* xpath, ...)
    {
      va_list arguments;
      va_start(arguments, xpath);
    
      size_t xpath_formatted_size = vsnprintf(NULL, 0, xpath, arguments) + 1;
      va_end(arguments);
      va_start(arguments, xpath);
      char* xpath_formatted = malloc(xpath_formatted_size);
      vsnprintf(xpath_formatted, xpath_formatted_size, xpath, arguments);
    
      va_end(arguments);
      return xpath_formatted;
    }
    Ответ написан
    Комментировать
  • Как правильно инициализировать массив в C?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    В этом коде проблема не в том, что массив d не инициализирован, а в том, что колическтво итераций цикла вывода массива d не зависит от того, сколько элементов было занесено в этот массив. Правильным решением было бы как-то их связать, например так:
    int i = 0, n;
    while (piece != NULL)
    {
        d[i] = piece;
        piece = strtok(NULL, " ");
        i++;
    }
    n = i;
    for (i = 0; i < n; i++) {
        if(i%2==0)
            printf("%s ",d[i]);
    }
    Ответ написан
    1 комментарий
  • Почему возникает такая проблема с динамическим массивом (Язык Си)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    ошибка возникает на моменте сдвига элементов. Как ее исправить?
    data = (Student*)realloc(data, count * sizeof(Student));
    
        for (int i = count; i > offset; i--)
        {
            data[i] = data[i - 1];
        }

    Этот код пишет за конец массива, потому что если в массиве count элементов, то последний имеет индекс count - 1. Этот цикл должен быть таким: for (int i = count - 1; i > offset; i--)
    Ответ написан
    Комментировать