2维阵列不打印预期答案

时间:2015-05-07 02:24:05

标签: c arrays

当我遍历2D数组元素以显示每个int时,我得到一串数字。我已经尝试了很多不同的东西来解决它,但我认为它是一个小的我可以忽略它将它们全部组合在一起。

无论如何,在header.h中我们创建

    typedef struct gol{
    int **board;
    size_t size;
}gol;

并在Main.c

void GOL_Opton1(){

    printf(" This is running Game Of Life on a default board\n");

    gol* mainGOL = (gol*)malloc(sizeof(gol));

    mainGOL = create_default_gol();
    print_gol(mainGOL);
}

gol* create_default_gol()
{
    gol* defaultGol = (gol*)malloc(sizeof(gol));

    int defaultArray[20][20];
    defaultGol->board = defaultArray;

    for (i = 0; i<20; i++){
        for (j = 0; j<20; j++){
           defaultGol->board[i,j] = 0;
     }
    }
    return defaultGol;
}

void print_gol(gol* g){
printf(" ------------------------------------------------\n");
for (i = 0; i<20; i++){
     for (j = 0; j<20; j++){
       printf("%d \t",g->board[i,j] );
     }printf("\n");
     }
}

从菜单调用选项1,然后gol中的棋盘数组填充一组0作为起点。

3 个答案:

答案 0 :(得分:4)

在那里有一些改进的地方。首先,在标题中,处理二维数组的更简单方法是存储指向第一个数组元素的指针以及大小。 (你的代码假设所有的主板都是方形的。我们现在就开始使用它。)

typedef struct { /* No need to name the struct if you typedef it */
    int *board;  /* We point to the first int, then calculate offsets manually */
    size_t size;
} gol;

然后我们可以手动计算数组中的位置。我们假设我们按以下顺序存储数字:

012
345
678

现在,让我们假设我们想要第一行中的元素,第二列 - 从零开始,所以实际上是中间行和最后一列 - 我们知道有三列每行,所以rows * columns_per_row + columns将是要查找的元素。

void GOL_Opton1(){
    printf(" This is running Game Of Life on a default board\n");

create_default_gol()已为您调用malloc。如果您首先为mainGOL分配malloc,则要求提供该内存但不要使用它,因为您会立即在mainGOL中存储另一个地址。这会导致内存泄漏。

    gol* mainGOL = create_default_gol();

    print_gol(mainGOL);
}

要避免&#34;魔术数字&#34;,我会使用#define。默认的电路板尺寸也可以通过这种方式轻松调节。

#define DEFAULT_GOL_SIZE 20

gol* create_default_gol()
{
    gol* defaultGol = (gol*)malloc(sizeof(gol));

声明一个数组通常会在堆栈上分配它。但是,您希望create_default_gol返回外部函数可以使用的gol,因此您需要在堆上分配它。 否则可能导致各种奇怪的行为。

    defaultGol->board = malloc(sizeof(int) * DEFAULT_GOL_SIZE * DEFAULT_GOL_SIZE);
    defaultGol->size  = DEFAULT_GOL_SIZE; /* and store the size */

此处,memset功能是将整个电路板快速设置为0的常用方法。

    /* memset avoids an ugly for loop here */
    memset(defaultGol->board, defaultGol->size * defaultGol->size, 0);

    return defaultGol;
}

void print_gol(gol* g){
    size_t row, col;
    printf(" ------------------------------------------------\n");

您希望print_gol函数能够处理大小不同于20的电路板,因此请将其概括为使用size成员。

    for (row = 0; row < g->size; row++) {
        for (col = 0; col < g->size; col++) {

这是上面讨论的偏移发挥作用的地方。您的原始代码为[i, j]不会执行您的意思;对于普通的二维数组,您需要[i][j],但在这种情况下,我们手动进行偏移计算以允许任意大小。

            printf("%d \t", g->board[col + row*g->size] );
        }
        printf("\n");
    }
}

答案 1 :(得分:1)

您遇到的具体问题是create_default_gol()

int defaultArray[20][20];
defaultGol->board = defaultArray;
[...]
return defaultGol;

defaultArray在堆栈中被分配,然后它的指针会转义该函数。您访问defaultArray(或->board时所写的数据将在您访问时消失。

您可以通过在堆上分配->board来解决此问题,其中malloc:一个用于整个电路板(malloc(20 * sizeof( int* ))),然后每行20个以上(malloc(20 * sizeof( int )))。

答案 2 :(得分:0)

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

typedef struct gol{
    int **board;
    size_t size;
}gol;


gol *create_gol(size_t size){
    size_t i, j;
    gol *aGol = (gol*)malloc(sizeof(gol));

    aGol->board = malloc(size * sizeof(int*));
    aGol->size = size;
    for (i = 0; i < size; i++){
        aGol->board[i] = malloc(size * sizeof(int));
        for (j = 0; j < size; j++){
           aGol->board[i][j] = 0;
        }
    }
    return aGol;
}

gol *create_default_gol(void){
    return create_gol(20);
}

void print_gol(gol *g){
    size_t i, j;
    printf("------------------------------------------------\n");
    for (i = 0; i < g->size; i++){
        for (j = 0; j < g->size; j++){
            printf("%d ", g->board[i][j] );
        }
        printf("\n");
    }
}

void GOL_Opton1(void){
    printf("This is running Game Of Life on a default board\n");

    gol *mainGOL = create_default_gol();
    print_gol(mainGOL);
}

int main(void){
    GOL_Opton1();
    //deallocate
    return 0;
}