繁体   English   中英

在结构中存储和访问2D阵列

[英]Storing and Accessing a 2D Array in a Struct

我正在尝试用C编写一个程序,该程序会根据用户输入生成螺旋形并将其打印到控制台。 我无法弄清楚如何访问在结构“ Spiral”中定义的2D数组“数据”。 如何解决“警告:来自不兼容指针类型的分配”错误?

#include <stdio.h>

typedef struct Spiral {
    int size;
    int **data;
} Spiral;

Spiral generateSpiral(int size);
void printSpiral(Spiral spiral);
static int rotate();

int main() {
    int size;
    scanf("%d", &size);
    Spiral spiral = generateSpiral(size);
    printSpiral(spiral);
    return 0;
}

Spiral generateSpiral(int size) {
    int data[size][size];
    int i;
    for (i = 0; i < size; i++) {
        int j;
        for (j = 0; j < size; j++) {
            data[i][j] = 0;
        }
    }

    for (i = 0; i < size; i++) {
        data[0][i] = 1;
    }

    int currX = 0;
    int currY = size - 1;

    for (i = size - 1; i > 0; i -= 2) {
        int j;
        for (j = 0; j < 2; j++) {
            int k;
            switch (rotate()) {
                case 0:
                    for (k = 0; k < i; k++) {
                        data[++currX][currY] = 1;
                    }
                    break;
                case 1:
                    for (k = i; k > 0; k--) {
                        data[currX][--currY] = 1;
                    }
                    break;
                case 2:
                    for (k = i; k > 0; k--) {
                        data[--currX][currY] = 1;
                    }
                    break;
                case 3:
                    for (k = 0; k < i; k++) {
                        data[currX][++currY] = 1;
                    }
                    break;
            }
        }
    }
    Spiral spiral;
    spiral.size = size;
    spiral.data = data;
    return spiral;
}

void printSpiral(Spiral spiral) {
    int i;
    for (i = 0; i < spiral.size; i++) {
        int j;
        for (j = 0; j < spiral.size; j++) {
            switch (spiral.data[i][j]) {
                case 0:
                    printf(" ");
                    break;
                case 1:
                    printf("#");
                    break;
            }
        }
        printf("\n");
    }
}

static int rotate() {
    static int val = 0;
    int tmp = val;
    val++;
    if (val > 3)
        val = 0;
    return tmp;
}

generateSpiral函数中,使结构指针指向局部变量data ,但是当函数返回data时,其范围超出范围,因此指针现在指向未分配的内存,从而导致未定义的行为

但是,这并不是唯一的问题:第二个问题是,指针的指针是一样的数组的数组,存储器布局是不同的。


对于最后一部分,我们来看一个例子。 可以说我们有以下声明

int a[2][2];

在内存中它将看起来像这样:

+---------+---------+---------+---------+
| a[0][0] | a[0][1] | a[1][0] | a[1][1] |
+---------+---------+---------+---------+

换句话说,所有数据都是连续的。

另一方面,如果您有一个声明,例如

int **p;

并为其正确分配数据,它看起来像

+------+------+-----+
| p[0] | p[1] | ... |
+------+------+-----+
  |      |      |
  |      |      v
  |      |      ...
  |      v
  |      +---------+---------+-----+
  |      | p[1][0] | p[1][1] | ... |
  |      +---------+---------+-----+
  v
  +---------+---------+-----+
  | p[0][0] | p[0][1] | ... |
  +---------+---------+-----+

内存不再连续。 不再有最大大小,指针指向内存的连续区域,但是无法知道该区域的大小。 您必须自己跟踪它。


解决这两个问题的简单方法是仅使用指向指针的指针,然后动态分配堆:

int **data;

// First allocate memory for `size` number of pointers
// I.e. we allocate an "array" of pointers
data = malloc(size * sizeof(int *));

// Then allocate each entry in the above allocated "array"
// I.e. make each pointer in the "array" point to an "array" of `int`
for (int i = 0; i < size; ++i)
    data[i] = malloc(size * sizeof(int));

现在,可以将本地变量data直接用于分配给spiral.data

但是有一个陷阱:在Java中,您不必释放分配的内存,而是自动处理的。 在C语言中,它不是自动处理的,您必须手动释放分配的内存,否则会发生内存泄漏

释放内存可以像

// First free all the "sub-arrays"
for (int i = 0; i < size; ++i)
    free(spiral.data[i]);

// Then free the top-level "array"
free(spiral.data);

关于指针,指针可以指向任何内存地址,并且实际上没有安全性或没有检查它是否指向有效位置。 另外,C不会对值和结构进行深层复制,如果您有一个指针并将其指向某处,则编译器或运行时系统不会进行复制。

关于作用域,Java也具有局部变量,就像在C中,当函数返回超出范围的局部变量一样。 Java和C之间的区别在于,如果您返回对本地对象的引用,则Java会跟踪该对象并将该对象保留在内存中,只要存在对该对象的引用即可。 C没有引用,指针只是一个整数,其值是内存中的地址,并且所指向的数据不知道有指向它的指针或指向它的指针。

您的问题是由于vectors函数返回的int与unsigned int之间不匹配。 将in i,j更改为size_t,以便它们也像矢量的大小一样是无符号整数。 这就是为什么您收到警告

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM