Глобальный массив переменных в C - PullRequest
0 голосов
/ 03 сентября 2011

Я пытаюсь создать глобальный массив, размер которого определяется внешним файлом параметров во время выполнения.

Я видел другие вопросы по этому поводу и пробовал:

int const Nt=1280;
double *Array = NULL;
Array = malloc(Nt * Nt * sizeof(double));

Однако я получаю такие ошибки, как:

Ошибка: конфликт типов для массива

Ошибка: элемент инициализатора не является константой

Как я могу создать такой глобальный массив без необходимости перекомпиляции каждый раз, когда мне нужно изменить его размер?

Ответы [ 4 ]

6 голосов
/ 03 сентября 2011

Назначение недопустимо в глобальном масштабе. Вместо этого вы должны сделать это в функции.

int const Nt = 1280;
double *Array = NULL;

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

const int Nt ; // Just declaration
Nt =  1280 ;   // Error. Assignment is not allowed at global scope.

const char* myName = "CHP" ;
int a[] = { 11,22,33,44,55 } ;

И аналогично в вашем примере Array это просто декларация. Выполните назначение в функции.

void assignArray() {

    Array = malloc(Nt * Nt * sizeof(double));

    // ...

    printf("%d", sizeof(Array)/sizeof(Array[0]); // Size which is nothing but Nt*Nt
                                                 // 0 to (Nt * Nt) - 1
}

А что касается ошибки сегментации, отправьте больше кода.

1 голос
/ 03 сентября 2011

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

РАБОТАЕТ:

int x = 1;

НЕ РАБОТАЕТ:

int x;
x = 1;

Вы должны переместить инициализатор в функцию, если вы не можете вписать его в эти правила.

0 голосов
/ 03 сентября 2011
double *Array = NULL;

Это хорошо (если вы включили заголовок, который определяет NULL, прежде чем писать).

Array = malloc(dim1 * dim2 * sizeof(double));

Вы говорите, что это дает:

Error: Conflicting types for Array
Error: Initializer element is not constant

Это потому, что компилятор наклоняется назад, чтобы принять ваш код, и ему удается интерпретировать Array как неявную переменную int, как если бы вы написали:

int Array = ...

Поскольку int не совпадает с double *, выдается ошибка конфликтующих типов.

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

if (Array == NULL)
    Array = malloc(dim1 * dim2 * sizeof(double));

Вы должны компилировать с более строгими предупреждениями компиляции. Я получаю:

$ cat x.c
#include <stdlib.h>
double *Array = NULL;
Array = malloc(23 * 37 * sizeof(double));
$ gcc -g -std=c99 -pedantic -Wall -Werror -c x.c
x.c:3:1: error: data definition has no type or storage class [-Werror]
x.c:3:1: error: type defaults to ‘int’ in declaration of ‘Array’ [-Werror]
x.c:3:1: error: conflicting types for ‘Array’
x.c:2:9: note: previous definition of ‘Array’ was here
x.c:3:9: error: initialization makes integer from pointer without a cast [-Werror]
x.c:3:1: error: initializer element is not constant
cc1: all warnings being treated as errors
$
0 голосов
/ 03 сентября 2011

Выполнить инициализацию в функции (например, в main ()):

int main() {
    Array = malloc(dim1 * dim2 * sizeof(double));
    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...