Страницы

Поиск по вопросам

среда, 29 января 2020 г.

Вернуть из функции массив на C

#c #массивы #указатели


Какой способ более правильный?


int *f() {
    int a[2] = {4, 5};
    int *p = a;
    p = (int*)malloc(2 * sizeof(int));
    p[0] = a[0];
    p[1] = a[1];
    return p;
}

void f(int *p)
{
    // Память по адресу `p` выделена вне функции
    int a[2] = {4, 5};
    p[0] = a[0];
    p[1] = a[1];
}


    


Ответы

Ответ 1



Какой вариант будет предпочтительнее зависит от контекста. Если уже имеется некоторое семейство функций (к которому также можно отнести f), выделяющих память при вызове, то предпочтение имеет смысл отдать первому варианту: int *f(). Если функции упомянутого семейства работают с заранее выделенной памятью, то разумно использовать второй вариант: void f(). В любом случае, в документации должно быть описано кто является ответственным за освобождение той или иной памяти, адресуемой указателем. При сравнении вариантов использования так же можно увидеть плюсы и минусы в обоих случаях: Вариант 1: int* ptr = f(); use(ptr); free(ptr); Вариант 2а: int* ptr = malloc(...); f(ptr); use(ptr); free(ptr); Вариант 2b: int ptr[] = {...}; f(ptr); use(ptr); Первый вариант явно требует работы с динамически выделяемой памятью. Во втором варианте помимо этого можно использовать и стековую или глобально выделенную память. Отказ от malloc/free может дать существенный прирост производительности в определенных ситуациях. Вариант 1 по сравнению с 2b для пользовательского кода будет короче, т.к. не требует явно выделять память, и переменная ptr инициализируется по месту. Из стандартных сишных функций для первого варианта вспомнилась пока только strdup. Хотя, думаю, должны быть и ещё варианты. Но функций второго типа однозначно больше.

Ответ 2



В программировании, только один критерий правильности. Это корректно работающий алгоритм. В обоих случаях алгоритм работает одинаково.

Комментариев нет:

Отправить комментарий