• Как освободить память сразу всем полям структуры?

    15432
    @15432
    Системный программист ^_^
    Написать конструктор и деструктор для структуры?

    struct BUFF
    {
        int * a;
        int * b;
        int * ...;
        BUFF();
        ~BUFF();
    };
    
    BUFF::BUFF()
    {
        a = new int[32];
        b = new int[32];
        .... = new int[32];
    
    }
    
    BUFF::~BUFF()
    {
        delete[] a;
        delete[] b;
        delete[] ...;
    }


    Если принципиально, можно создать массив из указателей
    struct BUFF
    {
        int * abc[3];
    };

    и в цикле их создавать / удалять
    for (int i = 0; i < 3; ++i)
    {
        delete[] buff.abc[i];
    }
    Ответ написан
    5 комментариев
  • Есть функция для вызова функций с параметрами загруженными в стек. Для x86 всё понятно, но как можно портировать на x86-64?

    @none7
    Код будет системозависимый. В Linux первые 6 аргументов передаются в регистрах (rdi, rsi, rdx, rcx, r8, r9), остальные по старинке . В Windows первые четыре в регистрах(rcx, rdx, r8, r9), остальные в стеке, НО место в стеке под первые 4 всё равно нужно выделить и лучше сохранить туда аргументы тоже; ради va_arg функций. Стек нужно выровнить по границе 16 байт ибо sse2 используется повсюду.
    Кстати лучше всё таки реализовывать такую функцию не в C++ исходнике, а в отдельном .s файле. Ведь если функция возвращает double, то нет никаких гарантий, что всё вернётся в целости.
    Ответ написан
    1 комментарий
  • Почему нужно указывать количество столбцов?

    @Free_ze
    Пишу комментарии в комментарии, а не в ответы
    В C++ на уровне языка не реализованы двумерные массивы, как это сделано, например, в C#. Здесь у нас есть лишь небольшой синтаксический сахар, в виде квадратных скобок.

    Например, все эти выражения по обращению к третьему элементу массива a равнозначны и будут компилироваться:
    a[2] <=> *(a+2) <=> *(2+a) <=> 2[a]

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

    В случае динамического выделения памяти
    const int ARRAY_SIZE = ...;
    
    int **arr = new int*[ARRAY_SIZE];
    for (int rown=0; rown<ARRAY_SIZE; ++rown) {
        arr[rown] = new int[ARRAY_SIZE];
    }

    мы и вовсе будем иметь дело с массивом указателей на строки, которые разбросаны по памяти стандартным аллокатором.

    Касаемо вопроса
    Таким образом, только МЫ знаем, что эта штука - двумерный массив, а не просто указатель на некоторую область памяти, как об этом думает функция.

    Пути решения в C++
    Конечно, стоит присмотреться к специальным классам вроде std::vector<T> и std::valarray<T>, на основе которых можно строить что-то вроде std::vector<std::vector<int>>. Эти типы уже не голые указатели и несут в себе свойство size(), с помощью которого мы можем оценивать размерности.
    Ответ написан
    2 комментария
  • Как писать тесты?

    MAKAPOH
    @MAKAPOH
    многостаночник
    Если речь идёт о модульных тестах то по сути это отдельные маленькие програмки которые проверяют работоспособность различных частей вашего проекта. В принципе это могут быть отдельные проекты в IDE. Для облегчения написания таких программ существуют специализированые библиотеки вроде google test.
    Ответ написан
    Комментировать