Определить массив глобально с переменным параметром в C

Вот код:

int EdgeCount = 0;
int numOfEdges = 0;

void addEdge() {
    // some code
    numOfEdges++;
}

int EdgeWeightArray[numOfEdges]; // error

Я хочу, чтобы этот глобальный массив с переменными параметрами использовал его позже, но я не мог этого сделать, потому что без #define мы не можем определить глобально параметры массива; и #define не переменная вещь. В моем коде numOfEdges является переменной, и я не мог сделать ее постоянной.


person umair mughal    schedule 14.06.2018    source источник
comment
Эта простая вещь меня очень смутила, и до сих пор, после долгих размышлений о хешировании и графиках, я не могу решить эту проблему.   -  person umair mughal    schedule 14.06.2018
comment
Массивы переменной длины (VLA) нельзя использовать в глобальной/файловой области. Либо переместите его в какую-либо функцию, либо выделите его динамически (malloc()). См. stackoverflow.com/questions/12363558/ для получения дополнительной информации.   -  person Acorn    schedule 14.06.2018
comment
Для этого следует использовать указатель: int* EdgeWeightArray = 0;. Затем нужно выделить память с помощью EdgeWeightArray = malloc(numOfEdges, sizeof(int));. Не забудьте освободить указатель после использования   -  person Cyclonecode    schedule 14.06.2018


Ответы (4)


EdgeWeightArray имеет глобальную область видимости, поэтому он должен быть фиксированного размера. Но numOfEdges, конечно, не константное выражение.

Какого размера вы ожидаете EdgeWeightArray? Ожидаете ли вы, что он будет расти при увеличении numOfEdges? Если это так, вам следует изучить динамическое распределение памяти; а именно malloc и realloc.

Краткий пример без проверки ошибок:

int numOfEdges = 0;
int *EdgeWeightArray;
void addEdge(some parameters) {
    //SOME CODE
    numOfEdges++;
    EdgeWeightArray = realloc(EdgeWeightArray, numOfEdges * sizeof(EdgeWeightArray[0]));
}
person Jonathon Reinhart    schedule 14.06.2018
comment
Можете ли вы сказать мне, почему вы используете размер как sizeof(EdgeWeightArray[0]). Он всегда дает размер '8'. Для печати я использую условие в 'цикле for' как sizeof(Array). Следовательно, он выполняется «8» раз независимо от того, что я меняю. Я решил эту проблему, изменив условие цикла for. Но могу ли я узнать причину, по которой размер остается «8»? - person umair mughal; 15.06.2018
comment
EdgeWeightArray = realloc(EdgeWeightArray, numOfEdges * sizeof(EdgeWeightArray[0])); РАЗМЕР = 8. EdgeWeightArray = realloc(EdgeWeightArray, anySize) РАЗМЕР ОСТАЕТСЯ 8. - person umair mughal; 15.06.2018

Почему бы не использовать глобальный указатель int и не выделить память с помощью malloc() с желаемым количеством элементов?

То, что вы пытаетесь сделать, невозможно, потому что память для глобальных переменных вычисляется во время компиляции, а значение numOfEdges обновляется во время выполнения.

person Soumen    schedule 14.06.2018

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

void defineSize() {
    numOfEdges++;
}

void useIt()
{
    int EdgeWeightArray[numOfEdges];
    /* Use EdgeWeightArray, once the function has been executed, \
       EdgeWeightArray will dissapear */
}
person Jose    schedule 14.06.2018
comment
С этим я не мог использовать EdgeWeightArray в другой функции... Хотя мне это нужно для дальнейшего использования - person umair mughal; 15.06.2018

Это расширение ответа Джонатона.

Если вы уже знаете, сколько элементов будет максимально для вашего массива, вы можете использовать фиксированный размер для своего массива. В данный момент это может быть быстрее, потому что перераспределения не происходит. Но вы должны убедиться, что при таком подходе выполняется соответствующая обработка ошибок. Это может быть довольно подвержено ошибкам.

Затем вам понадобится счетчик для отслеживания ваших граней, но, похоже, у вас уже есть один из них.

Тогда ваш код будет выглядеть так:

#define MAX_EDGE_COUNT 1000
int EdgeCount = 0;

void addEdge() {
    // some code
    EdgeWeightArray[EdgeCount] = newEdge;
    EdgeCount++;
}

int EdgeWeightArray[MAX_EDGE_COUNT];
person Phillipp Mevenkamp    schedule 14.06.2018
comment
Да, но элементы моего массива не фиксируются. Они изменяются по мере увеличения numOfEdges на 1. В main() я мог вызвать функцию три раза ИЛИ мог использовать «n» раз. - person umair mughal; 15.06.2018
comment
В яблочко. Но, может быть, у вас уже есть верхний предел, чтобы вы могли использовать этот предел. В качестве альтернативы вы можете использовать С++ std::vector, который автоматически увеличивает свой размер. - person Phillipp Mevenkamp; 15.06.2018