Calloc для массива массива с отрицательным индексом в C

У меня есть массив массива с отрицательным индексом. Это массив с реальными размерами [dim_y + 40][dim_x + 40], но пользователь использует массив так, будто он имеет размеры [dim_y][dim_x]. Сначала у меня были глобальные и уже определены размеры dim_x, dim_y, поэтому у меня было это

int map_boundaries[dim_y + 40][dim_x + 40];
int (*map)[dim_x+40] = (int(*)[dim_x+40])&map_boundaries[20][20];

Это работало нормально. Теперь мне нужно, чтобы размеры dim_y и dim_x были переменными, и под этим я подразумеваю, что я хочу, чтобы массив «карта» имел не фиксированный размер, а динамический, мне нужно прочитать dim_y, dim_x от пользователя и массив «карта» чтобы быть глобальным, поэтому у меня есть

int **map_boundaries;

и я использую calloc в main()

map_boundaries = (int **)calloc(dim_y + 40,sizeof(int*)); 
for(i = 0; i < dim_y + 40; i++){
    map_boundaries[i] = (int *)calloc(dim_x + 40,sizeof(int));
}

, но я не знаю, как объявить вторую строку

Для лучшего понимания границ я сделал то, что написано во втором комментарии здесь: http://everything2.com/title/Negative+array+indexing


person user3143155    schedule 14.10.2014    source источник
comment
Я предполагаю, что вы имеете в виду, что вам нужно, чтобы размеры были переменными для измерения верхнего уровня. т.е. map_boundaries[0] будет указывать на массив, который может быть другим измерением, чем map_boundaries[1] и т. д. Если это не то, что вы имели в виду, возможно, уточните свой вопрос (и включите строку calloc, которую вы, кажется, оставили вышел без особых причин).   -  person WhozCraig    schedule 14.10.2014
comment
@WhozCraig извините, мне нужно, чтобы dim_y, dim_x были переменными   -  person user3143155    schedule 14.10.2014
comment
да, мы получили это. Опять же, вы имеете в виду, что dim_x должна иметь возможность варьироваться для каждой строки? Это имеет значение. Теперь вы используете объявления VLA, которые подходят для любых данных dim_x и dim_y, которые помещаются в допустимое пространство вашей автоматической переменной, но не будут работать, если вы хотите, скажем, первое чтобы в строке было 3 элемента, во второй — 5 и т. д. Это то, что вам нужно?   -  person WhozCraig    schedule 14.10.2014
comment
@WhozCraig нет, мне просто нужно получить два значения от пользователя, dim_x и dim_y, как будто у меня есть обычный двойной массив, например, dim_y = 10, dim_x = 15. Таким образом, каждая строка имеет одинаковое количество столбцов.   -  person user3143155    schedule 14.10.2014
comment
C99 поддерживает VLA, так что после того, как вы получите их от пользователя, вы можете объявить их по старинке. это называется массивом переменной длины.   -  person CS Pei    schedule 14.10.2014
comment
@JohnSmith, спасибо за ответ, не могли бы вы опубликовать эту строку, как она должна быть?   -  person user3143155    schedule 14.10.2014
comment
Тогда ваш вопрос несколько неясен. Какое отношение ко всему этому имеют отрицательные индексы? Извините, если это кажется излишним, но вы можете ясно видеть свою проблему; мы не делаем. В чем на самом деле проблема? (т.е. какое отношение отрицательные индексы имеют к любому из этого.   -  person WhozCraig    schedule 14.10.2014
comment
@WhozCraig Я создаю симуляцию, моя карта имеет размеры dim_y и dim_x, но мне нужны дополнительные границы только для меня, пользователю они не нужны. Так что у меня есть дополнительное пространство, которое я только вижу. В этом причина отрицательного индекса. Но мне просто нужно объявить его с помощью переменных dim_x и dim_y вместо статического   -  person user3143155    schedule 14.10.2014
comment
@JohnSmith, я не могу этого сделать, мне нужно, чтобы переменная «карта» была глобальной   -  person user3143155    schedule 14.10.2014
comment
Каков диапазон допустимых индексов, который вам требуется? Судя по вашему общему описанию, вы хотите использовать map[x][y] с x в диапазоне -20 .. x_dim+20 и с y в диапазоне -20 .. y_dim + 20. Это правильно? И вам нужно, чтобы x_dim и y_dim можно было выбирать во время выполнения, а не константы времени компиляции, а смещения (-20, +20) фиксируются во время компиляции.   -  person Jonathan Leffler    schedule 14.10.2014
comment
@JonathanLeffler да, смещения фиксированы. Например, map[0][0] — это map_boundaries[20][20]. Допустим, для пользователя диапазон строк равен (0, dim_y), а для меня (-20, dim_y + 20). Я хочу, чтобы смещения (-20, 20) были фиксированными, какими бы ни были dim_y, dim_x. До сих пор я определял dim_y и dim_x, но теперь мне просто нужно, чтобы пользователь определял их во время выполнения.   -  person user3143155    schedule 14.10.2014
comment
Это выполнимо, но сложно. Я до сих пор не совсем понимаю, что видит «пользователь» (программист) по сравнению с тем, что видите «вы» (поставщик библиотеки?). Мне нужно прочитать код и комментарии, чтобы понять имена переменных. Если я правильно интерпретирую ваш последний комментарий, ... о, он изменился и пришел в соответствие с тем, что я ожидал. Фу!   -  person Jonathan Leffler    schedule 14.10.2014
comment
@JonathanLeffler позволяет сказать, что массив представляет собой квадрат. Итак, у нас есть большой квадрат и маленький в нем. Я (тот, кто пишет код) вижу большую, а пользователь видит только маленькую, которая в большой. Границы только для меня   -  person user3143155    schedule 14.10.2014


Ответы (2)


Я бы выделил один массив:

int* storage = calloc((dim_x + 40) * (dim_y + 40), sizeof(int));

Затем я бы вернул его пользователю в непрозрачной структуре, например:

struct map {
  int* storage;
  size_t dim_x;
  size_t dim_y;
};

Затем я бы определил функцию индексации для пользователя:

int* get_cell(struct map* m, x, y) {
  return &m->storage[(x + 20) + (m->dim_x + 40) * (y + 20)];
}

И, возможно, получить всю строку, если пользователь хочет прочитать/записать несколько элементов в одной строке:

int* get_row(struct map* m, y) {
  return get_cell(m, 0, y);
}

size_t get_row_size(struct map* m) {
  return m->dim_x;
}

Поскольку вы хотите, чтобы измерения определялись во время выполнения, вам в любом случае потребуется выполнить вычисления индекса во время выполнения.

person John Zwinck    schedule 14.10.2014

Вот моя версия кода. Значение int **map — это то, что и пользователь, и библиотека используют для доступа к данным. Структура Matrix инкапсулирует всю информацию о массиве, включая элемент, который используется для инициализации map. Код устанавливает размеры, выделяет и инициализирует структуру, затем инициализирует массив, а затем использует его так, как это сделал бы пользователь и как это сделала бы библиотека. Наконец, выделенная память освобождается.

На практике вы, вероятно, захотите разделить это на несколько отдельных функций.

Источник: 2da.c:

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include "stderr.h"

typedef struct Matrix
{
    int  *map_base;
    int **map_rows;
    int   x_dim;
    int   y_dim;
    int   extra;
    int **map;
} Matrix;

int main(void)
{
    Matrix m;
    int x_dim = 8;
    int y_dim = 6;
    int extra = 5;

    /* Allocation */
    m.extra = extra;
    m.x_dim = x_dim;
    m.y_dim = y_dim;
    int x_cells = x_dim + 2 * extra;
    int y_cells = y_dim + 2 * extra;
    m.map_base = calloc(x_cells * y_cells, sizeof(**m.map));
    if (m.map_base == 0)
        err_syserr("Failed to allocate %zu bytes memory\n",
                   x_cells * y_cells * sizeof(**m.map));
    m.map_rows = calloc(x_cells, sizeof(*m.map));
    if (m.map_rows == 0)
        err_syserr("Failed to allocate %zu bytes memory\n",
                   x_cells * sizeof(*m.map));
    //printf("Map base: 0x%.8" PRIXPTR "\n", (uintptr_t)m.map_base);
    //printf("Map rows: 0x%.8" PRIXPTR "\n", (uintptr_t)m.map_rows);
    for (int i = 0; i < x_cells; i++)
    {
        m.map_rows[i] = &m.map_base[i * y_cells + extra];
        //printf("Row[%2d]   0x%.8" PRIXPTR "\n", i, (uintptr_t)m.map_rows[i]);
    }
    m.map = &m.map_rows[extra];

    int **map = m.map;
    //printf("Map:      0x%.8" PRIXPTR "\n", (uintptr_t)map);

    /* Initialization */
    int x_min = -extra;
    int y_min = -extra;
    int x_max = x_dim + extra;
    int y_max = y_dim + extra;
    printf("Initialization:\n");
    for (int i = x_min; i < x_max; i++)
    {
        for (int j = y_min; j < y_max; j++)
        {
            map[i][j] = i * 100 + j;
            //printf("[%2d,%2d] = %4d\n", i, j, map[i][j]);
        }
    }

    printf("User view:\n");
    for (int i = 0; i < x_dim; i++)
    {
        for (int j = 0; j < y_dim; j++)
            printf("[%2d,%2d] = %4d\n", i, j, map[i][j]);
    }

    printf("Library view:\n");
    for (int i = x_min; i < x_max; i++)
    {
        for (int j = y_min; j < y_max; j++)
            printf("[%2d,%2d] = %4d\n", i, j, map[i][j]);
    }

    /* Deallocation */
    free(m.map_base);
    free(m.map_rows);

    return 0;
}

Пример вывода

При запуске под valgrind 3.10.0 в Mac OS X 10.9.5 с GCC 4.9.1 я получил следующий вывод . Заголовок "stderr.h" находится в $HOME/inc и объявляет err_syserr(), а libjl.a находится в $HOME/lib/64 и обеспечивает реализацию для err_syserr(), функции, которая сообщает данное сообщение об ошибке и ошибку, идентифицированную errno, и завершает работу. На этот раз мне лень писать код в этой программе. (Выполните поиск «[c] user: 15168 err_syserr» в SO, чтобы найти Защита сегмента общей памяти с помощью семафора не работает, код которого по существу эквивалентен. В этом ответе я не вызывал err_setarg0() в коде.)

$ gcc -O3 -g -I/Users/jleffler/inc -std=c11 -Wall -Wextra -Wmissing-prototypes \
>     -Wstrict-prototypes -Wold-style-definition -Werror 2da.c -o 2da \
>     -L/Users/jleffler/lib/64 -ljl
$ valgrind ./2da
==26293== Memcheck, a memory error detector
==26293== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==26293== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==26293== Command: 2da
==26293== 
Initialization:
User view:
[ 0, 0] =    0
[ 0, 1] =    1
[ 0, 2] =    2
[ 0, 3] =    3
[ 0, 4] =    4
[ 0, 5] =    5
[ 1, 0] =  100
[ 1, 1] =  101
[ 1, 2] =  102
[ 1, 3] =  103
[ 1, 4] =  104
[ 1, 5] =  105
[ 2, 0] =  200
[ 2, 1] =  201
[ 2, 2] =  202
[ 2, 3] =  203
[ 2, 4] =  204
[ 2, 5] =  205
[ 3, 0] =  300
[ 3, 1] =  301
[ 3, 2] =  302
[ 3, 3] =  303
[ 3, 4] =  304
[ 3, 5] =  305
[ 4, 0] =  400
[ 4, 1] =  401
[ 4, 2] =  402
[ 4, 3] =  403
[ 4, 4] =  404
[ 4, 5] =  405
[ 5, 0] =  500
[ 5, 1] =  501
[ 5, 2] =  502
[ 5, 3] =  503
[ 5, 4] =  504
[ 5, 5] =  505
[ 6, 0] =  600
[ 6, 1] =  601
[ 6, 2] =  602
[ 6, 3] =  603
[ 6, 4] =  604
[ 6, 5] =  605
[ 7, 0] =  700
[ 7, 1] =  701
[ 7, 2] =  702
[ 7, 3] =  703
[ 7, 4] =  704
[ 7, 5] =  705
Library view:
[-5,-5] = -505
[-5,-4] = -504
[-5,-3] = -503
[-5,-2] = -502
[-5,-1] = -501
[-5, 0] = -500
[-5, 1] = -499
[-5, 2] = -498
[-5, 3] = -497
[-5, 4] = -496
[-5, 5] = -495
[-5, 6] = -494
[-5, 7] = -493
[-5, 8] = -492
[-5, 9] = -491
[-5,10] = -490
[-4,-5] = -405
[-4,-4] = -404
[-4,-3] = -403
[-4,-2] = -402
[-4,-1] = -401
[-4, 0] = -400
[-4, 1] = -399
[-4, 2] = -398
[-4, 3] = -397
[-4, 4] = -396
[-4, 5] = -395
[-4, 6] = -394
[-4, 7] = -393
[-4, 8] = -392
[-4, 9] = -391
[-4,10] = -390
[-3,-5] = -305
[-3,-4] = -304
[-3,-3] = -303
[-3,-2] = -302
[-3,-1] = -301
[-3, 0] = -300
[-3, 1] = -299
[-3, 2] = -298
[-3, 3] = -297
[-3, 4] = -296
[-3, 5] = -295
[-3, 6] = -294
[-3, 7] = -293
[-3, 8] = -292
[-3, 9] = -291
[-3,10] = -290
[-2,-5] = -205
[-2,-4] = -204
[-2,-3] = -203
[-2,-2] = -202
[-2,-1] = -201
[-2, 0] = -200
[-2, 1] = -199
[-2, 2] = -198
[-2, 3] = -197
[-2, 4] = -196
[-2, 5] = -195
[-2, 6] = -194
[-2, 7] = -193
[-2, 8] = -192
[-2, 9] = -191
[-2,10] = -190
[-1,-5] = -105
[-1,-4] = -104
[-1,-3] = -103
[-1,-2] = -102
[-1,-1] = -101
[-1, 0] = -100
[-1, 1] =  -99
[-1, 2] =  -98
[-1, 3] =  -97
[-1, 4] =  -96
[-1, 5] =  -95
[-1, 6] =  -94
[-1, 7] =  -93
[-1, 8] =  -92
[-1, 9] =  -91
[-1,10] =  -90
[ 0,-5] =   -5
[ 0,-4] =   -4
[ 0,-3] =   -3
[ 0,-2] =   -2
[ 0,-1] =   -1
[ 0, 0] =    0
[ 0, 1] =    1
[ 0, 2] =    2
[ 0, 3] =    3
[ 0, 4] =    4
[ 0, 5] =    5
[ 0, 6] =    6
[ 0, 7] =    7
[ 0, 8] =    8
[ 0, 9] =    9
[ 0,10] =   10
[ 1,-5] =   95
[ 1,-4] =   96
[ 1,-3] =   97
[ 1,-2] =   98
[ 1,-1] =   99
[ 1, 0] =  100
[ 1, 1] =  101
[ 1, 2] =  102
[ 1, 3] =  103
[ 1, 4] =  104
[ 1, 5] =  105
[ 1, 6] =  106
[ 1, 7] =  107
[ 1, 8] =  108
[ 1, 9] =  109
[ 1,10] =  110
[ 2,-5] =  195
[ 2,-4] =  196
[ 2,-3] =  197
[ 2,-2] =  198
[ 2,-1] =  199
[ 2, 0] =  200
[ 2, 1] =  201
[ 2, 2] =  202
[ 2, 3] =  203
[ 2, 4] =  204
[ 2, 5] =  205
[ 2, 6] =  206
[ 2, 7] =  207
[ 2, 8] =  208
[ 2, 9] =  209
[ 2,10] =  210
[ 3,-5] =  295
[ 3,-4] =  296
[ 3,-3] =  297
[ 3,-2] =  298
[ 3,-1] =  299
[ 3, 0] =  300
[ 3, 1] =  301
[ 3, 2] =  302
[ 3, 3] =  303
[ 3, 4] =  304
[ 3, 5] =  305
[ 3, 6] =  306
[ 3, 7] =  307
[ 3, 8] =  308
[ 3, 9] =  309
[ 3,10] =  310
[ 4,-5] =  395
[ 4,-4] =  396
[ 4,-3] =  397
[ 4,-2] =  398
[ 4,-1] =  399
[ 4, 0] =  400
[ 4, 1] =  401
[ 4, 2] =  402
[ 4, 3] =  403
[ 4, 4] =  404
[ 4, 5] =  405
[ 4, 6] =  406
[ 4, 7] =  407
[ 4, 8] =  408
[ 4, 9] =  409
[ 4,10] =  410
[ 5,-5] =  495
[ 5,-4] =  496
[ 5,-3] =  497
[ 5,-2] =  498
[ 5,-1] =  499
[ 5, 0] =  500
[ 5, 1] =  501
[ 5, 2] =  502
[ 5, 3] =  503
[ 5, 4] =  504
[ 5, 5] =  505
[ 5, 6] =  506
[ 5, 7] =  507
[ 5, 8] =  508
[ 5, 9] =  509
[ 5,10] =  510
[ 6,-5] =  595
[ 6,-4] =  596
[ 6,-3] =  597
[ 6,-2] =  598
[ 6,-1] =  599
[ 6, 0] =  600
[ 6, 1] =  601
[ 6, 2] =  602
[ 6, 3] =  603
[ 6, 4] =  604
[ 6, 5] =  605
[ 6, 6] =  606
[ 6, 7] =  607
[ 6, 8] =  608
[ 6, 9] =  609
[ 6,10] =  610
[ 7,-5] =  695
[ 7,-4] =  696
[ 7,-3] =  697
[ 7,-2] =  698
[ 7,-1] =  699
[ 7, 0] =  700
[ 7, 1] =  701
[ 7, 2] =  702
[ 7, 3] =  703
[ 7, 4] =  704
[ 7, 5] =  705
[ 7, 6] =  706
[ 7, 7] =  707
[ 7, 8] =  708
[ 7, 9] =  709
[ 7,10] =  710
[ 8,-5] =  795
[ 8,-4] =  796
[ 8,-3] =  797
[ 8,-2] =  798
[ 8,-1] =  799
[ 8, 0] =  800
[ 8, 1] =  801
[ 8, 2] =  802
[ 8, 3] =  803
[ 8, 4] =  804
[ 8, 5] =  805
[ 8, 6] =  806
[ 8, 7] =  807
[ 8, 8] =  808
[ 8, 9] =  809
[ 8,10] =  810
[ 9,-5] =  895
[ 9,-4] =  896
[ 9,-3] =  897
[ 9,-2] =  898
[ 9,-1] =  899
[ 9, 0] =  900
[ 9, 1] =  901
[ 9, 2] =  902
[ 9, 3] =  903
[ 9, 4] =  904
[ 9, 5] =  905
[ 9, 6] =  906
[ 9, 7] =  907
[ 9, 8] =  908
[ 9, 9] =  909
[ 9,10] =  910
[10,-5] =  995
[10,-4] =  996
[10,-3] =  997
[10,-2] =  998
[10,-1] =  999
[10, 0] = 1000
[10, 1] = 1001
[10, 2] = 1002
[10, 3] = 1003
[10, 4] = 1004
[10, 5] = 1005
[10, 6] = 1006
[10, 7] = 1007
[10, 8] = 1008
[10, 9] = 1009
[10,10] = 1010
[11,-5] = 1095
[11,-4] = 1096
[11,-3] = 1097
[11,-2] = 1098
[11,-1] = 1099
[11, 0] = 1100
[11, 1] = 1101
[11, 2] = 1102
[11, 3] = 1103
[11, 4] = 1104
[11, 5] = 1105
[11, 6] = 1106
[11, 7] = 1107
[11, 8] = 1108
[11, 9] = 1109
[11,10] = 1110
[12,-5] = 1195
[12,-4] = 1196
[12,-3] = 1197
[12,-2] = 1198
[12,-1] = 1199
[12, 0] = 1200
[12, 1] = 1201
[12, 2] = 1202
[12, 3] = 1203
[12, 4] = 1204
[12, 5] = 1205
[12, 6] = 1206
[12, 7] = 1207
[12, 8] = 1208
[12, 9] = 1209
[12,10] = 1210
==26293== 
==26293== HEAP SUMMARY:
==26293==     in use at exit: 29,341 bytes in 374 blocks
==26293==   total heap usage: 452 allocs, 78 frees, 36,581 bytes allocated
==26293== 
==26293== LEAK SUMMARY:
==26293==    definitely lost: 0 bytes in 0 blocks
==26293==    indirectly lost: 0 bytes in 0 blocks
==26293==      possibly lost: 0 bytes in 0 blocks
==26293==    still reachable: 4,096 bytes in 1 blocks
==26293==         suppressed: 25,245 bytes in 373 blocks
==26293== Rerun with --leak-check=full to see details of leaked memory
==26293== 
==26293== For counts of detected and suppressed errors, rerun with: -v
==26293== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$

«Все еще доступный» блок — это буфер для stdout; если бы я включил fclose(stdout); перед возвратом из main(), он пошел бы. Библиотека времени выполнения Mac OS X также выделяет много памяти, но это использование указано в скрытой информации.


Комментарий и ответ

Я делаю всю инициализацию, как вы видите, в 2 строки. Но проблема не в инициализации; проблема в том, что в каждом кадре значения карты меняются. Поэтому мне нужна просто «карта», которая указывает прямо на «карту границ». map[0][0] это boundaries_map[20][20] и так далее. Я попытался объявить глобальный **map, а затем записать свою вторую строку в основную, но получаю ошибку о приведении. (*map)[dim_x+40] это **map не так ли?

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

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

Приведенный ниже код можно рассматривать как упражнение по созданию VLA. Он использует malloc() для создания VLA, записывая место его создания в указатель на VLA. Это можно передать функции так же, как можно передать VLA на основе стека. Код корректно компилируется в GCC 4.9.1 на Mac OS X 10.9.5:

$ gcc -g -O3 -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Werror \
>     2dv.c -o 2dv 

Он работает чисто и без утечек в соответствии с valgrind.

Источник: 2dv.c:

#include <stdio.h>
#include <stdlib.h>

static void dump_vla_1(int x_size, int y_size, int vla[x_size][y_size]);
static void dump_vla_2(int x_min, int y_min, int x_size, int y_size,
                       int vla[x_size][y_size]);
static void dump_vla_3(int x_min, int x_max, int y_min, int y_max,
                       int x_size, int y_size, int vla[x_size][y_size]);

int main(void)
{
    int extra = 3;
    int x_base = 5;
    int y_base = 4;
    int x_size = x_base + 2 * extra;
    int y_size = y_base + 2 * extra;

    int (*vla)[x_size][y_size] = calloc(x_size * y_size, sizeof(int));

    for (int i = 0; i < x_size; i++)
        for (int j = 0; j < y_size; j++)
            (*vla)[i][j] = (i + 1) * 100 + (j + 1);

    for (int i = 0; i < x_size; i++)
    {
        for (int j = 0; j < y_size; j++)
            printf(" %4d", (*vla)[i][j]);
        putchar('\n');
    }

    dump_vla_1(x_size, y_size, *vla);
    dump_vla_2(0, 0, x_size, y_size, *vla);

    /* Harsh cast! */
    int (*vla_2)[x_size][y_size] = (int (*)[x_size][y_size])&(*vla)[extra][extra];

    dump_vla_2(-extra, -extra, x_size, y_size, *vla_2);

    dump_vla_3(-extra, x_size - extra, -extra, y_size - extra, x_size, y_size, *vla_2);
    dump_vla_3(0, x_base, 0, y_base, x_size, y_size, *vla_2);

    free(vla);
    return 0;
}

static void dump_vla_1(int x_size, int y_size, int vla[x_size][y_size])
{
    printf("Matrix %dx%d\n", x_size, y_size);
    for (int i = 0; i < x_size; i++)
    {
        for (int j = 0; j < y_size; j++)
            printf(" %4d", vla[i][j]);
        putchar('\n');
    }
}

static void dump_vla_2(int x_min, int y_min, int x_size, int y_size,
                       int vla[x_size][y_size])
{
    printf("Matrix %dx%d (%d..%d, %d..%d)\n",
           x_size, y_size, x_min, x_min + x_size - 1, y_min, y_min + y_size - 1);
    for (int i = x_min; i < x_min + x_size; i++)
    {
        for (int j = y_min; j < y_min + y_size; j++)
            printf(" %4d", vla[i][j]);
        putchar('\n');
    }
}

static void dump_vla_3(int x_min, int x_max, int y_min, int y_max,
                       int x_size, int y_size, int vla[x_size][y_size])
{
    printf("Matrix %dx%d (%d..%d, %d..%d)\n",
           x_size, y_size, x_min, x_max, y_min, y_max);
    for (int i = x_min; i < x_max; i++)
    {
        for (int j = y_min; j < y_max; j++)
            printf(" %4d", vla[i][j]);
        putchar('\n');
    }
}

Обратите внимание на использование *vla и *vla_2 для передачи VLA функциям. Поскольку переменные vla и vla_2 являются указателями на VLA, *vla является VLA, которую ожидают функции.

Выход:

  101  102  103  104  105  106  107  108  109  110
  201  202  203  204  205  206  207  208  209  210
  301  302  303  304  305  306  307  308  309  310
  401  402  403  404  405  406  407  408  409  410
  501  502  503  504  505  506  507  508  509  510
  601  602  603  604  605  606  607  608  609  610
  701  702  703  704  705  706  707  708  709  710
  801  802  803  804  805  806  807  808  809  810
  901  902  903  904  905  906  907  908  909  910
 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
Matrix 11x10
  101  102  103  104  105  106  107  108  109  110
  201  202  203  204  205  206  207  208  209  210
  301  302  303  304  305  306  307  308  309  310
  401  402  403  404  405  406  407  408  409  410
  501  502  503  504  505  506  507  508  509  510
  601  602  603  604  605  606  607  608  609  610
  701  702  703  704  705  706  707  708  709  710
  801  802  803  804  805  806  807  808  809  810
  901  902  903  904  905  906  907  908  909  910
 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
Matrix 11x10 (0..10, 0..9)
  101  102  103  104  105  106  107  108  109  110
  201  202  203  204  205  206  207  208  209  210
  301  302  303  304  305  306  307  308  309  310
  401  402  403  404  405  406  407  408  409  410
  501  502  503  504  505  506  507  508  509  510
  601  602  603  604  605  606  607  608  609  610
  701  702  703  704  705  706  707  708  709  710
  801  802  803  804  805  806  807  808  809  810
  901  902  903  904  905  906  907  908  909  910
 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
Matrix 11x10 (-3..7, -3..6)
  101  102  103  104  105  106  107  108  109  110
  201  202  203  204  205  206  207  208  209  210
  301  302  303  304  305  306  307  308  309  310
  401  402  403  404  405  406  407  408  409  410
  501  502  503  504  505  506  507  508  509  510
  601  602  603  604  605  606  607  608  609  610
  701  702  703  704  705  706  707  708  709  710
  801  802  803  804  805  806  807  808  809  810
  901  902  903  904  905  906  907  908  909  910
 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
Matrix 11x10 (-3..8, -3..7)
  101  102  103  104  105  106  107  108  109  110
  201  202  203  204  205  206  207  208  209  210
  301  302  303  304  305  306  307  308  309  310
  401  402  403  404  405  406  407  408  409  410
  501  502  503  504  505  506  507  508  509  510
  601  602  603  604  605  606  607  608  609  610
  701  702  703  704  705  706  707  708  709  710
  801  802  803  804  805  806  807  808  809  810
  901  902  903  904  905  906  907  908  909  910
 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
Matrix 11x10 (0..5, 0..4)
  404  405  406  407
  504  505  506  507
  604  605  606  607
  704  705  706  707
  804  805  806  807
person Jonathan Leffler    schedule 14.10.2014
comment
Спасибо за ваш ответ, но мой симулятор уже активно использует графический процессор, я делаю всю инициализацию, как вы видите, в 2 строки. Но проблема не в инициализации, проблема в том, что в каждом кадре значения карты меняются. Поэтому мне нужна только «карта», которая указывает непосредственно на «карту границ». map[0][0] — это bounds_map[20][20] и так далее. Я попытался объявить глобальную карту **, а затем записать вторую строку в основную, но получаю сообщение об ошибке приведения. (*карта)[dim_x+40] это **карта, не так ли? - person user3143155; 14.10.2014