C 2D阵列旋转

时间:2012-04-02 00:04:30

标签: c

我有一个表示网格的2D指针设置,网格由包含1/0或空列的列组成(即在任何单元格中不包含1)。此功能顺时针旋转网格90度,除了......

我认为我的malloc可能有问题,因为它有效但我在dmalloc中遇到了很多纠察队列错误。

我是否分配了错误的内存量?

此外,我想交换* width和* height的值来表示网格的新宽度和高度,但是当我尝试这个时,程序只是第二次旋转时会出现段错误。

3 个答案:

答案 0 :(得分:1)

再看一下旋转网格的代码。我认为您不想混用xy坐标,因此像*width - 1 - y这样的索引看起来很可疑。例如,假设*width = 3*height = 5。然后y的范围是0到4,最后可以得到newg[3 - 1 - 4] = newg[-2]

此外,如果您按照分配orig的方式分配newg,则需要将其释放为:

for (x=0; x < *width; x++) {
  free (orig[x]);  // Free the individual columns
}
free (orig); // Free the array of pointers.

答案 1 :(得分:1)

所以* width是orig第一维的维度,因此它应该是newg第二维的大小。

类似地,* height应该是newg的第一个大小,因此两组malloc大小的翻转方式错误。

我认为将值命名为orig_max_x和orig_max_y会更清楚,那么应该清楚该函数是否以错误的方式使用这些值。

    newg = malloc (*height * sizeof(char *));

    // Initialise each column
    for (x = 0; x < *height; x++) {
        newg[x] = malloc (*width);
        for (y = 0; y < *width; y++)
            newg[x][y] = 0;
    }

此外,如果您想要从spin()

返回值,不会释放任何的newg存储空间

编辑:我仍然有一些讨厌的*宽度和*高度混合。抱歉。 我强烈建议这些名称应与他们所谈论的内容相关,orig_width, orig_height会帮助我阅读代码。

这可能是我做的:

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

char** alloc_rectangle(int *width, int *height);
void free_rectangle(char **orig, int *width);
char** spin (char **orig, int *width, int *height);

int main (int argc, const char * argv[]) {
    int width = 20;
    int height = 30;

    char** orig = alloc_rectangle(&width, &height);
    char** newg = spin(orig, &width, &height);


    return 0;
}

char** alloc_rectangle(int *width, int *height) 
{
    char **newg = calloc (*width, sizeof(char *));

    // Initialise each column
    for (int x = 0; x < *width; x++) {
        newg[x] = calloc (*height, sizeof(char));
    }
    return newg;
}

void free_rectangle(char **orig, int *width)
{
    // free memory for old grid
    for (int x = 0; x < *width; x++) {
        if (orig[x] != NULL) {
            free (orig[x]);
        }
    }

    free (orig);
}

char** spin (char **orig, int *width, int *height) 
{
    int x;
    int y;

    char **newg = alloc_rectangle(height, width);

    // Rotate
    for (x = 0; x < *width; x++) {
        for (y = 0; y < *height; y++)
            if (orig[x] != NULL) 
                newg[*height - 1 - y][x] = orig[x][y];
    }

    return newg;
}

警告未经测试的代码 - 对所有人来说都很有趣: - )

我不认为自由创作是旋转的工作。我更喜欢它只是腾出空间来保持旋转的结果。因此,为了使事情更整洁,我将一个矩形释放到它自己的功能中。同样,我总是希望一致地分配矩形,这将是它自己的功能。

答案 2 :(得分:0)

我刚刚写了这篇文章并且它似乎与我在其上运行的几个测试一起工作正常。

char **rotate(char **original, int *width, int *height)
{
    int t_width = *height;
    int t_height = *width;

    char **newgrid = (char**)calloc(t_height, sizeof(char*));

    for(int y = 0; y < t_height; y++)
    {
        newgrid[y] = (char*)calloc(t_width, sizeof(char));
        for(int x = 0; x < t_width; x++)
            newgrid[y][x] = original[x][y];         
    }

    for(int y = 0; y < *height; y++)
        free(original[y]);
    free(original);

    *width = t_width;
    *height = t_height;

    return newgrid;
}

如果有任何问题,请告诉我。