Объявление глобальной переменной (массива) внутри функции в C

Мне нужно объявить глобальный двумерный массив в C.

Размер массива определяется шириной и высотой данного изображения.

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

Итак, как я могу объявить массив глобальным, если я знаю его размер только после выполнения функции main()?

РЕДАКТИРОВАТЬ: (я также пробовал другие решения, поэтому этот комментарий относится ко всем из них) @Mimisbrunnr Во-первых, спасибо за быстрый ответ!

I've tried but I can't see to make it work. I'm probably missing something stupid, but how does "array" becomes global? It says on test() that 'array' is undeclared

int *buffer;

int main() {
    int i;
    int x_size=100;
    int y_size=100;

    int * buffer = malloc(sizeof(int)*x_size*y_size);
    int ** array = malloc(sizeof(int*)*y_size);

    for(i = 0; i<y_size; i++) {
        array[i]=&buffer[i*x_size];
    }

    array[0][1] = 5;
    test();
    return 0;
}

void test(){
    printf("%d",array[0][1]);
}


person Avenger    schedule 22.07.2011    source источник
comment
Вам действительно нужна глобальная переменная (указатель)? Не могли бы вы передать его вместо этого? Его передача усложняет прототипы функций, но упрощает управление, особенно при работе с многопоточными приложениями.   -  person pmg    schedule 22.07.2011
comment
@pmg: OTOH, усложнение прототипа функции делает явным то, с чем работает функция.   -  person ninjalj    schedule 22.07.2011
comment
Да @ниндзя. У меня есть отличное доказательство того, что глобальные переменные — это плохо, но это поле для комментариев слишком маленькое для этого :)   -  person pmg    schedule 22.07.2011
comment
Я мог бы передать это... но, как вы сказали, это действительно усложнит мой код. И так как я сейчас просто делаю это, чтобы выучить C, я хотел бы знать все варианты решения этой проблемы, чтобы позже, когда я столкнусь с ней в реальной программе, я смог бы это сделать. наилучшим образом.   -  person Avenger    schedule 23.07.2011


Ответы (3)


На самом деле я не выполнял этот код, но это должно помочь вам начать.

int x_size = 100;
int y_size = 100;

int ** array;
array = malloc(sizeof(int *)*y_size);
for(int i = 0; i<y_size; i++)
array[i] = malloc(sizeof(int)*x_size);

larsmans сделал хорошее замечание.

что насчет этого?

int x_size = 100;
int y_size = 100;

int * buffer = malloc(sizeof(int)*x_size*y_size);

int ** array = malloc(sizeof(int *)*y_size);
for(int i = 0; i<y_size; i++)
array[i] = &buffer[i*x_size];

Похоже, вам может понадобиться базовый учебник по C.

int *buffer;
int **array;
int main()
{
int x_size=100;
int y_size=100;
int i;
/*int * */ buffer = malloc(sizeof(int)*x_size*y_size);
/*int ** */ array = malloc(sizeof(int*)*y_size);
for(i = 0; i<y_size; i++)
 array[i]=&buffer[i*x_size];
array[0][1] = 5;
test();
return 0;
}
void test()
{
printf("%d",array[0][1]);
}
person user606723    schedule 22.07.2011
comment
Это немного компактнее, но вам все еще нужно два вызова free, чтобы избавиться от данных (я знаю, что это глобально...). Кроме того, это по-прежнему менее эффективно с точки зрения памяти, чем использование одного массива с соответствующими приемами индексации, и может пострадать от потери локальности ссылки. - person Fred Foo; 22.07.2011
comment
Возможно, но я думаю, что это хороший компромисс для тех, кто не готов использовать «соответствующие приемы индексации». - person user606723; 22.07.2011
comment
Я пытался комментировать, но я не могу делать новые строки в комментариях, поэтому я отредактировал свой основной пост. Спасибо! - person Avenger; 23.07.2011
comment
Спасибо! Он отлично работает! Я сейчас изучаю C, вся штуковина с указателями для меня очень сложна - все *, **, $, malloc и т. д. В любом случае, большое спасибо за комментарии! хотя я не уверен, что понимаю это, я попытаюсь перечитать главу о переменных и указателях в моей книге! - person Avenger; 23.07.2011

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

char * buffer;

int main(void) {

    buffer = malloc( /* Width * Height */ );

}
person zellio    schedule 22.07.2011
comment
@ user: 606723: Это более безопасный и эффективный способ работы с двумерными массивами, чем указатели на указатели. - person Fred Foo; 22.07.2011

используйте переменную static (указатель) и динамически выделяйте массив с помощью malloc.

person eyalm    schedule 22.07.2011