Задать вопрос
  • Ошибки в функции создания двумерного динамического массива С++. Как исправить?

    includedlibrary
    @includedlibrary
    Понимаю, что легче было бы это сделать через тот же тип double, но мне уже интересно, возможно ли это через void?


    Звучит как: "Понимаю, что проще поглощать пищу через рот, но уже интересно, возможно ли через заднее отверстие".

    Что мешает сразу сделать нормально и вернуть значение из функции:
    double** Array(unsigned int rows, unsigned int colms)
    {
        double** array2d = new double* [rows];
        for (unsigned int i = 0; i < rows; i++)
            array2d[i] = new double[colms];
        return array2d;
    }
    Ответ написан
    Комментировать
  • Для чего тесты пишут?

    includedlibrary
    @includedlibrary
    Тесты пишут, чтобы при изменениях в коде их прогонять и проверять, что определённое в тестах поведение не ломается. Да, можно каждый раз всё вручную прогонять, но вот для примера, у нас в проекте тысячи две автотестов, каждый раз всё это вручную прогонять ни у кого возможности нет
    Ответ написан
  • Как сделать одномерный массив в си?

    includedlibrary
    @includedlibrary
    Либо заранее просить пользователя ввести размер и использовать for:
    int size;
    scanf("%d", &size);
    int *list = malloc(sizeof(int) * size);
    for(int i = 0; i < size; i++)
        scanf("%d", &list[i]);


    Либо как сделали вы.

    Такой код, кстати, list[size++] = n; в какой-то момент приведёт к segfaul, потому что list, очевидно, фиксированного размера, а работа предполагается с массивом переменной длины. Почитайте про malloc/realloc
    Ответ написан
    Комментировать
  • Как использовать libstdc на Bare Metal?

    includedlibrary
    @includedlibrary
    Как верно заметили выше, никак. Но вообще, в ядре можно свои аналогичные функции написать, правда, они не всегда будут иметь тот же интерфейс, что и функции из стандартной библиотеки.
    Ответ написан
    4 комментария
  • Как корректно передать данные из std.ArrayList в Slice?

    includedlibrary
    @includedlibrary
    Ну, как минимум, вы неправильно считываете строки.
    while (reader.streamUntilDelimiter(line.writer(), '\n', null)) : (line_no += 1) {
            defer line.clearRetainingCapacity(); // по выходу из цикла буфер будет освобождён
            ...
            // тут вы для нескольких строк используете один и тот же буфер
           // даже если не освобождать память, у всех 26 структур будет указатель на один и тот же буфер, но
          // с разными смещениями
            statements[line_no] = .{ .content = line.items[(i + 1)..] };
    }
    Ответ написан
    Комментировать
  • Как создать правило make для компиляции списка .c в список .out?

    includedlibrary
    @includedlibrary
    Например, так:
    CC=gcc
    CFLAGS=-std=c11 -Wall -O3
    LDFLAGS=
    OBJ=$(patsubst %.c, %.o, $(wildcard *.c))
    TARGET=main
    .PHONY: all clean
    all: $(TARGET)
    $(TARGET): $(OBJ)
    	$(CC) $(LDFLAGS) $(OBJ) -o $(TARGET)
    %.o: %.c
    	$(CC) $(CFLAGS) -c $< -o $@
    clean:
    	rm -f $(OBJ) $(TARGET)
    Ответ написан
    Комментировать
  • Есть ли тайловый оконный менеджер, который работает с мышкой?

    includedlibrary
    @includedlibrary
    i3
    Ответ написан
    Комментировать
  • Возможно ли как-то использовать обычную функцию заместо макро-функции?

    includedlibrary
    @includedlibrary
    Да, возможно, но вы это делаете не правильно.
    #define PORTB 0x04
    #define PORTB0 0
    
    void bit_set(uint8_t port, uint8_t bit)
    {
        port |= (1 << bit);
    }
    
    int main(void)
    {
        bit_set(PORTB, PORTB0);
    }


    Здесь вообще ничего не делается, это же void функция. Если поменять её тип на uint8_t и добавить return, то компилятор всё равно оставит и функцию и её вызов, потому что она не объявлена статической, а значит может вызываться откуда-то ещё.
    #include <stdint.h>
    #include <stdio.h>
    
    #define PORTB 0x04
    #define PORTB0 0
    
    // вызов функции останется
    uint8_t bit_set(uint8_t port, uint8_t bit)
    {
        return port |= (1 << bit);
    }
    
    int main(void)
    {
        uint8_t res = bit_set(PORTB, PORTB0);
        printf("%hhd\n", res);
    }


    Если же сделать функцию статической, то её вызов будет заинлайнен, но лучше тогда сразу static inline использовать:
    #include <stdint.h>
    #include <stdio.h>
    
    #define PORTB 0x04
    #define PORTB0 0
    
    // А вот так функция будет заинлайнена
    static inline uint8_t bit_set(uint8_t port, uint8_t bit)
    {
        return port |= (1 << bit);
    }
    
    int main(void)
    {
        uint8_t res = bit_set(PORTB, PORTB0);
        printf("%hhd\n", res);
    }

    И да, чтобы переиспользовать static inline функции, их надо объявлять в заголовочных файлах, объявить прототип в заголовочном файле, а тело в .c файле не выйдет.
    Рекомендую проверить самостоятельно с помощью https://godbolt.org. Не забудьте, что без указания флагов оптимизации, ничего заинлайнено не будет, даже если объявить функцию, как static inline
    Ответ написан
  • Как исправить ошибку при выводе матрицы?

    includedlibrary
    @includedlibrary
    int input(int *n, int *m, int ***matrix, int *flag) {
        char ch;
        // Зачем считывать ch, я не понял. Также проверка у вас неправильная.
        // scanf возвращает число считанных элементов, вам надо сравнивать это
        // число с 2, так как вы считываете n и m.
        // if(scanf("%d%d", n,m) != 2 || *n <= 0 || *m <= 0)
        //     return 0;
        if (((scanf("%d%d%c", n,m, &ch)) || (ch != '\n')) && ((*n <= 0) || (*m <=0))){
            *flag =0;
            // Тут просто сделать return 0;
        } else{
            // Всё, что ниже, нужно вынести из else блока, а сам else блок убрать
            **matrix = (int *)malloc((*n) * sizeof(int*));
            for (int i; i < *n; i++ ){
            for (int j; j < *m; j++) {
                **matrix = (int *)malloc((*n * *m) * sizeof(int));
    
                // if(scanf("%d", &((*matrix)[i][j])) != 1)
                //     return 0;
                if (scanf("%d", matrix[i][j])) {
                    
                } else {
                   *flag =0;
                }
            }
        }
        } 
    // return 1;
    return *flag =1;
    }


    Тут вы используете неверный указатель:
    scanf("%d", matrix[i][j]) // так не надо
    scanf("%d", &((*matrix)[i][j])) // надо так
    scanf("%d", *(*matrix + i) + j) // или так


    Не понятно, зачем flag делать указателем, можно объявить его в input, присвоить 1 или 0 и вернуть. Кстати, у вас сравнение неверное, сейчас возвращается всегда 1:
    // очевидно, имелось в виду *flag == 1
    // Но вообще, можно просто вернуть *flag.
    // Или везде, заменить присваивание *flag = что_то на return что_то
    return *flag =1;


    Так же у вас абсолютно неверно выделяется память:
    // Тут каст неверный, должно быть (int**),
    // Но в си касты void* к другим типам указателей
    // можно опускать. Также нужна лишь одна операция разыменовывания для matrix
    **matrix = (int *)malloc((*n) * sizeof(int *));
    // Забыли присвоить 0 в i
    for (int i; i < *n; i++) {
      // А этот цикл надо сделать после выделения памяти для m столбцов
      // для ввода данных в выделенную память. Тут тоже забыли присвоить 0 в j.
      for (int j; j < *m; j++) {
        // Вот тут вы перезаписываете первую строку matrix,
        // хотя хотели выделить m столбцов для i строки.
        // До перазаписи дело, правда, не дойдёт, так как на предыдущем шаге
        // вы сделали два разыменовывания вместо одного и уже словили segfault
        **matrix = (int *)malloc((*n * *m) * sizeof(int));
        // ...
      }
    }


    Исправляется элементарно:
    *matrix = malloc(*n * sizeof(int*));
    for (int i = 0; i < *n; i++) {
        // *matrix - указатель на двумерный массив,
        // *matrix + i - указатель на строку (которая является указателем на одномерный массив),
        // *(matrix + i) = ... - присваивание указателю на строку адреса выделенной памяти
        *(*matrix + i) = malloc(*m * sizeof(int));
        for(int j = 0; j < *m; j++) {
            // Ввод данных
        }
    }


    Ну и совет на будущее - не используйте scanf, хотя проблема сейчас и не в ней. Желательно проверять результат malloc на NULL, чтобы корректно завершать программу в случае нехватки памяти, а не выводить segfault, или не завершать, а просто вызвращать ошибку и продолжать работу дальше. Также не используйте конструкции вида int ***matrix, лучше сделайте функцию, которая принимает n и m и возвращает указатель на матрицу, также сделайте отдельную функцию для ввода значений и вывода.

    int** create_matrix(int n, int m);
    bool read_matrix(int n, int m, int **matrix);
    void write_matrix(int n, int m, int **matrix);
    void free_matrix(int n, int m, int **matrix);


    Ну и 2 мерный массив можно сделать через одномерный, так будет меньше вызовов malloc, а значит потенциально меньше обращений к ядру. Также, если данные всего двумерного массива будут лежать последовательно, велика вероятность, что в циклах большая часть значений будет браться из кэша, а не из памяти, что даст выигрыш в скорости.
    int n = 10, int m = 5;
    int *matrix = malloc(sizeof(int) * n * m);
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            matrix[i * m + j] // обращение к элементу в i строке в j столбце
        }
    }


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

    includedlibrary
    @includedlibrary
    Файл был пустой, поэтому clang не мог его скомпилировать. Либо вы компилировали другой файл, а не тот, что открыт в VScode, либо VScode не сохранял содержимое файла на диск.
    Ответ написан
    Комментировать
  • В чем ошибка кода?

    includedlibrary
    @includedlibrary
    int cubeI(int num) {
        if (num > 5) {
            cout << num << " ";
            return pow(num, 3);
        }
    }
    
    long cubeL(long num) {
        if (num > 5) {
            cout << num << " ";
            return pow(num, 3);
        }
    }

    Если элемент меньше или равен пяти, функции должны возвращать исходное значение. Нужно добавить return num после if, иначе будет возвращено то, что на момент выхода из функции было в регистре rax (если у вас amd64 архитектура).
    Ответ написан
    7 комментариев
  • На сколько безопасен sql запрос с подстановкой в него данных без обработки с клиента?

    includedlibrary
    @includedlibrary
    Можно прокинуть что угодно, следовательно так делать не безопасно. Чтобы избежать инъекций, используйте подготовленные выражения
    Ответ написан
    2 комментария
  • Как исправить ошибку Е0028 Выражение должно иметь константное значение на С?

    includedlibrary
    @includedlibrary
    Компилятор студии не поддерживает массивы переменной длины. Надо использовать malloс и free для выделения памяти. Но лучше не объявлять массивы переменной длины, так как это может вызвать переполнение стека при больших размерах.
    Ответ написан
    Комментировать
  • Верно ли я понял процесс преобразование целого типа данных в символьный на C?

    includedlibrary
    @includedlibrary
    В таблице ASCII все символы имеют 7 битный код, цифры расположены последовательно от 0 до 9, поэтому прибавление к значению от 0 до 9 кода сивола '0', вы получаете код символа, соответствующего данному значению. Но тип переменной не меняется, как был int, так им и остался.
    Ответ написан
    6 комментариев
  • Почему некорректно работает перегруженный оператор постинкремента?

    includedlibrary
    @includedlibrary
    На этой строке вы хотите скопировать вектор:
    Vector result = *this;

    Однако, у вас нигде нет конструктора на этот случай, поэтому у вас тупо копируется указатель, а не данные, которые по нему лежат. Надо добавить конструктор для этого:
    Vector(Vector &v) {
        this->dim = new double[v.dimCount];
        this->dimCount = v.dimCount;
        memcpy(this->dim, v.dim, this->dimCount * sizeof(double));
    }
    Ответ написан
  • На каком языке для каких целей писать проги под Symbian?

    includedlibrary
    @includedlibrary
    Симбиан мёртв, поэтому очевидно, что вы собираетесь писать для удовольствия. В таком случае берите тот язык, который больше нравится.
    Ответ написан
    Комментировать
  • Как записать текст из базы данных в txt файл делая отступы?

    includedlibrary
    @includedlibrary
    myfile = open('test.txt', 'w')
    Когда открываете файл в режиме 'w', вы открываете его на перезапись. Можно вместо 'w' передать 'a', тогда всё будет записываться в конец файла. Но, во-первых, в вашем коде один файл на всех пользователей (не знаю, была ли цель сделать именно так, поэтому пишу), во-вторых, могут быть дубликаты, т.е. желательно добавить проверку на уникальность. Можно взять СУБД (если нужно хранить всё в файле, то можно использовать sqlite), тогда и работать с несколькими пользователями будет проще и проверку на укникальность самому писать не придётся. Также использование СУБД позволит в будущем без проблем хранить какие-либо ещё данные, кроме URL прокси серверов
    Ответ написан
    Комментировать
  • Что за тип Unit в Haskel Rust Kotlin? Чем отличается от Void?

    includedlibrary
    @includedlibrary
    Тип Void в Haskell, в отличие от (), не имеет никаких значений. То есть вы не можете создать значение, имеющее данный тип. В свою очередь у () есть одно допустимое значение. Тип Void также встречается в системах проверки доказательств для обозначения ложности утверждения.
    Ответ написан
    Комментировать
  • Почему при любой комбинации значений в матрице удаляется первый элемент?

    includedlibrary
    @includedlibrary
    Переведите код из картинки в текст. А проблема в том, что надо в if одно равно на два поменять:
    if(mat[i] == mat[i + 1])

    Так как сейчас вы всегда в i элемент кладёте i + 1 элемент вместо сравнения. Вложенный цикл при этом исполняется всегда, если i + 1 элемент не равен нулю.
    Ответ написан
    Комментировать