Эффективна ли передача статического массива функции?

#define BUFF_SIZE 100000
unsigned char buffer[BUFF_SIZE];

void myfunc(unsigned char[],int,int);
void myfuncinfunc(unsigned char[],int,int);

int main()
{
int a = 10, b = 10;
myfunc(buffer,a,b);
}

void myfunc(unsigned char array[],int a,int b)
{
int m,n;
//blah blah
myfuncinfunc(array,m,n);
}

void myfuncinfunc(unsigned char array[],int a, int b)
{
//blah blah
}

Я хочу знать следующее:

  1. Я создал статический массив, как показано выше, для основной функции. Это эффективно? Было бы лучше, если бы я вместо этого использовал точку и malloc?

  2. Я знаю, что он не использует стек, поэтому, когда я передаю массив во внутренние функции, будет ли он создавать копию всего массива или просто отправлять местоположение первой записи?

  3. При работе с «массивом» в функции «myfunc» я работаю непосредственно со статическим определенным массивом или некоторой локальной копией?

  4. Внутри функции «myfunc», когда мы передаем массив в функцию «myfuncinfunc», будет ли она снова отправлять в стек только первое местоположение или полную копию массива?

Спасибо за чтение вопроса и будем очень признательны за любую помощь! Я новичок в C и пытаюсь изучить его в Интернете.


person Rakshit Kothari    schedule 03.03.2014    source источник
comment
В вашем примере buffer является глобальным, поэтому вам не нужно передавать его в качестве параметра другим функциям.   -  person Tom Fenech    schedule 03.03.2014
comment
@TomFenech - Даже если функция определена в других файлах C?   -  person Rakshit Kothari    schedule 03.03.2014
comment
Если функция определена в другом месте, ситуация меняется. Вы можете передать его как параметр или объявить в общем заголовке, что оба файла #include.   -  person Tom Fenech    schedule 03.03.2014
comment
@TomFenech - Но тогда повторный вызов массива в качестве параметра в функции был бы неэффективным. Скажем, у меня есть 500 вызовов myfunc и 1000 вызовов myfuncinfunc. Не лучше ли НЕ передавать его в качестве параметра для всех этих итераций? Как ответил кто-то ниже, он создает указатель на первое место в нашем стеке. Если эта операция повторяется для такого количества вызовов, не будет ли это неэффективно?   -  person Rakshit Kothari    schedule 03.03.2014
comment
@RakshitKothari Только если у вас есть 1000 рекурсивных вызовов функций. Тогда это было бы ужасно неэффективно. Для 1000 обычных вызовов функций вы зарезервируете место только для одного указателя.   -  person Lundin    schedule 03.03.2014
comment
Я думаю, вы рискуете преждевременной оптимизацией. Маловероятно, что передача указателя будет узким местом в любом нетривиальном примере.   -  person Tom Fenech    schedule 03.03.2014


Ответы (2)


  1. Я не понимаю, как это может быть более или менее эффективным, чем массив в куче.
  2. Он распадается на указатель на первую запись.
  3. Следовательно, это не локальная копия, а сам массив.
  4. То же.

Кстати, если a и b являются индексами в массиве, рассмотрите возможность использования для них типа size_t (это unsigned int гарантированно достаточно большой для индексирования массивов).

person Medinoc    schedule 03.03.2014
comment
Спасибо! Итак, просто для подтверждения, определенный статический массив не использует наш стек, верно? Идет в кучу? Спасибо за подсказку size_t! - person Rakshit Kothari; 03.03.2014
comment
@RakshitKothari Ничего не попадает в кучу, если вы явно не вызываете malloc. - person Lundin; 03.03.2014
comment
Он идет в сегменте статических данных (который не является ни стеком, ни кучей). - person Medinoc; 03.03.2014

  1. Я создал статический массив, как показано выше, для основной функции. Это эффективно? Было бы лучше, если бы я вместо этого использовал точку и malloc?

Дайте определение «эффективный». Статически выделенные массивы всегда быстрее, чем динамические, из-за накладных расходов времени выполнения на выделение/освобождение.

В этом случае вы выделяете огромное количество 100 КБ, что может быть очень неэффективным с точки зрения использования памяти.

Кроме того, ваш процесс может иметь не так много доступной статической памяти, в зависимости от ОС. Поэтому в настольных системах рекомендуется выделять память в куче всякий раз, когда вы используете большие объемы данных.

  1. Я знаю, что он не использует стек, поэтому, когда я передаю массив во внутренние функции, будет ли он создавать копию всего массива или просто отправлять местоположение первой записи?

Вы не можете передавать массивы по значению в C. Таким образом, указатель на первый элемент массива будет сохранен в стеке и передан функции.

  1. При работе с «массивом» в функции «myfunc» я работаю непосредственно со статическим определенным массивом или некоторой локальной копией?

Непосредственно на статическом массиве. Опять же, вы не можете передавать массивы по значению.

Внутри функции «myfunc», когда мы передаем массив в функцию «myfuncinfunc», будет ли она снова отправлять в стек только первое местоположение или полную копию массива?

Указатель на первый элемент.

person Lundin    schedule 03.03.2014
comment
Понятно! Как я уже спрашивал в своем комментарии выше, не могли бы вы сказать мне, будет ли лучше, если я глобально прикреплю свой массив ко всем файлам C? передача массива в качестве параметра на каждой итерации снова и снова использует стек; Могу ли я вызвать параметр непосредственно в любой файл C, который использует массив? - person Rakshit Kothari; 03.03.2014
comment
@RakshitKothari Очень плохая практика - использовать глобальные переменные, передавать их как параметр. Единственное, что размещается в стеке, — это одна переменная-указатель, которая занимает так мало места, что ею можно пренебречь. Компилятор может даже оптимизировать его, так что пусть компилятор беспокоится об эффективности. - person Lundin; 03.03.2014