инициализировать глобальный двумерный массив целых чисел C во время выполнения - PullRequest
1 голос
/ 29 января 2012

Мне нужно хранить массив точек (x, y). Я читаю точки из файла, и количество точек не является постоянным, но я могу получить их в первой строке файла. Поэтому я пишу процедуру load () для загрузки точек из файла и сохранения их в глобальном массиве. Не работает Мой код:

int *array[][]; // this is a pointer to a 2-dimensional array??

void load(){
..
int tempArray[2][n];  //n is the first line of the file
..
array = tempArray;
}

Ответы [ 4 ]

3 голосов
/ 29 января 2012

Вы пытаетесь вернуть указатель на память, локальную для функции, которая определяет переменную.Как только эта функция перестает работать («выходит из области видимости»), эта память повторно используется для чего-то другого, поэтому запрещено пытаться ссылаться на нее позже.

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

Прототипом функции может быть:

int * read_points(const char *filename, size_t *num_points);

Где filename - это, конечно, имя файла, который нужно открыть, num_points - этоустановить количество найденных точек, а возвращаемое значение - указатель на массив, содержащий значения x и y с чередованием.Таким образом, это напечатало бы координаты первой загруженной точки:

size_t num_points;
int    *points;

if((points = load_points("my_points.txt", &num_points)) != NULL)
{
  if(num_points > 0)
    printf("the first point is (%d,%d)\n", points[0], points[1]);
  free(points);
}
2 голосов
/ 29 января 2012

Эта ваша декларация не работает:

int *array[][]; // this is a pointer to a 2-dimensional array??

Сначала он пытается объявить двумерный массив int *. Во-вторых, когда вы объявляете или определяете массив, должны быть указаны все размеры, кроме первого (size).

int (*array)[][2];   // This is a pointer to a 2D array of unknown size

Теперь это можно использовать в основном варианте вашей функции. Это вариант, потому что я сначала неправильно понял ваш вопрос.

void load(void)
{
    ...
    int tempArray[n][2];  // Note the reversed order of dimensions!
    ...
    array = &tempArray;
    ...there must be some code here calling functions that use array...
    array = 0;
}

Обратите внимание, что для присвоения требуется & в имени массива. В других функциях вам нужно написать:

n = (*array)[i][j];

Обратите внимание, что присвоение адреса локального массива глобальной переменной опасно. Как только функция load() вернется, область хранения для tempArray больше не будет действительной. Следовательно, единственный безопасный способ сделать присваивание - это затем вызвать функции, которые ссылаются на глобальную переменную, и затем сбросить глобальную переменную перед выходом из функции. (Или, по крайней мере, признайте, что значение недопустимо. Но установка его в ноль - нулевой указатель - скорее обеспечит сбой программы, чем просто доступ к случайной памяти.

В качестве альтернативы вам нужно получить динамическое выделение памяти для массива.

Ваш вопрос на самом деле хочет сделать глобальный указатель на VLA, массив переменной длины, где размерность переменной не первая:

int tempArray[2][n];  // Note the reversed order of dimensions!

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

Итак, есть несколько проблем:

  • Обозначение указателей на массивы
  • Инициализация указателей на массивы
  • Назначение глобальных указателей локальным переменным
  • Вы не можете иметь глобальные указатели на многомерные VLA, где переменные длины не в первом измерении.
  • Вы должны минимизировать использование глобалов.
0 голосов
/ 29 января 2012

Вы пытаетесь назначить массив, но в массивах C не может быть назначен.

Используйте memcpy, чтобы скопировать один массив в другой массив.Элементы массива в C гарантированно будут смежными.

int bla[N][M] = {0};
int blop[N][M];

/* Copy bla array to blop */
memcpy(blop, bla, sizeof blop);
0 голосов
/ 29 января 2012

Более элегантная версия может выглядеть так:

typedef struct point_ { int x; int y; } point;

point * create_array(size_t n)
{
    return calloc(n, sizeof(point));
}

void free_array(point * p)
{
    free(p);
}

int main()
{
    size_t len = read_number_from_file();
    point * data = create_array(len);

    if (!data) { panic_and_die(); }

    for (size_t i = 0; i != len; ++i)
    {
        /* manipulate data[i].x and data[i].y */
    }

    free_array(data);
    data = 0;            /* some people like to do this */
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...