在 C 语言中二元分配二维矩阵

Dinamically allocating a 2D matrix in C

提问人:gustavo moretto itikawa 提问时间:7/26/2023 最后编辑:Vlad from Moscowgustavo moretto itikawa 更新时间:7/26/2023 访问量:65

问:

我正在尝试在 C 中分配一个 2D 矩阵,它已经被灌输了。我需要它已经初始化以形成目录,之后将用于下一个功能。

黑客帝国

char matriz2D[8][24] ={{'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'},
                            {'#','\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '#'},
                            {'#','\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '#'},
                            {'#','\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '#'},
                            {'#','\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '#'},
                            {'#','\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '#'},
                            {'#','\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '#'},
                            {'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'}};

我该如何分配它?我正在尝试代码

matriz2D[alocador1][alocador2] =(char**)malloc(sizeof(char));

但是编译器向我抛出错误:

error: assignment to 'char' from 'char **' makes integer from pointer without a cast [-Wint-conversion]

如何继续在内存中分配此矩阵?

C 矩阵 多维数组 malloc 动态内存分配

评论

0赞 Eric Postpischil 7/26/2023
不能分配已初始化的矩阵,除非将内存初始化为零。 为您提供未初始化的内存。您必须在单独的步骤中将数据放入其中。“试图在 C 中分配一个 2D 矩阵,这已经被灌输了”是什么意思?callocmalloc
0赞 gustavo moretto itikawa 7/26/2023
这是因为当我尝试将矩阵传递给函数时,它会向我抛出内存越界错误,从而表明矩阵未被矩阵访问
2赞 chux - Reinstate Monica 7/26/2023
@gustavomorettoitikawa “因为当我尝试将矩阵传递给函数时......” --> 发布该示例代码。
0赞 gustavo moretto itikawa 7/26/2023
函数的代码如下,我正在尝试制作一个基本的路径查找器函数以供以后使用,但是当我尝试使用矩阵内的数据时,这些函数会给我带来内存越界,就像在语句中一样if(matrix[element_positionY+1][element_position]!='\0') { printf("The cell above is clear!\n"); return VALID_MOVEMENT; }else { printf("The position above is occupied!\n"); return INVALID_MOVEMENT; }
0赞 Andrew Henle 7/26/2023
阅读: 正确分配多维数组

答:

0赞 KamilCuk 7/26/2023 #1

不要让它变得困难。使用结构。

struct your_matrix_s {
   char matriz2D[8][24];
};
struct your_matrix_s *matrix = malloc(sizeof(*matrix));

不要投射 malloc 的结果。

如果你准备迎接挑战,那么你可能需要一个指向数组的指针:

char (*another_matrix)[24] = malloc(8 * sizeof(*another_matrix));
1赞 Vlad from Moscow 7/26/2023 #2

不能动态分配已初始化的数组,除非该函数可以按零初始化分配的内存。calloc

因此,首先您需要为二维数组分配内存,然后根据需要设置其元素。

要将矩阵动态分配为二维数组,您可以编写例如

enum { M = 8, N = 24 };
char ( *matriz2D )[N] = calloc( 1, sizeof( char[M][N] ) );

memset( matriz2D[0], '#', sizeof( matriz2D[0] ) );
memset( matriz2D[M-1], '#', sizeof( matriz2D[M-1] ) );

for ( size_t i = 1; i < M-1; i++ )
{
    matriz2D[i][0] = '#';
    matriz2D[i][N-1] = '#';
}

注意这一点而不是幻数,最好使用命名常量。还要记住,矩阵的元素不包含字符串。824

0赞 Chris 7/26/2023 #3

您已经分配了矩阵。只是不是动态的

鉴于此矩阵在堆栈上的大小并不令人望而却步,因此需要动态分配的唯一原因是,如果您在一个函数中创建它,并且需要它在该函数的生命周期中存活。

你的问题暗示你的问题在于将其传递给函数。当你的矩阵被传递给一个函数时,它会衰减为一个指针,但什么样的指针呢?好吧,它衰减为指向 24 个字符数组的指针。

如果您尝试编写以下内容,您将收到来自编译器的警告,然后在我的测试中,收到分段错误。

void foo(char **m) {
    m[0][0] = 'A';
}
test.c:33:9: warning: incompatible pointer types passing 'char[8][24]' to parameter of type 'char **' [-Wincompatible-pointer-types]
    foo(matriz2D);
        ^~~~~~~~
test.c:3:17: note: passing argument to parameter 'm' here

但是,如果您编写以下内容,则函数参数已正确键入,并且按预期工作。

void foo(char (*m)[24]) {
    m[0][0] = 'A';
}

如果你需要能够传递不同维度的矩阵,我们也可以传递一个参数。size_t

void foo(size_t n, char (*m)[n]) {
    m[0][0] = 'A';
}

对于矩阵,这称为:

foo(24, matriz2D);

评论

0赞 gustavo moretto itikawa 7/26/2023
尝试了参数,但编译器抛出此错误:ISO C 禁止嵌套函数 [-Wpedantic]|“,因此不起作用。
0赞 gustavo moretto itikawa 7/26/2023
问题是,当我尝试将矩阵传递给另一个函数时,就会出现问题
1赞 arfneto 7/26/2023 #4

有很多方法可以写这个。要走的路取决于您将使用该区域的方式。

首先要问的问题是矩阵维度是否始终相同

如果这就是你所需要的,我将向你展示一个更简单的写法的例子。char[8][23]

无论如何,您需要知道这是另一回事,必须按原样仔细构建。这些是非常有用的构造,但可能在这里你不需要它们。char **char ** **

如果您的用例是用于更动态的回写,我可以发布替代方案使用或其他东西。char **

示例的输出

Set 1 [ a b c d e f ]
Set 2 [ g h i j k l ]

allocating new area for matrix

copy set 1 to new area
In new area: [ a b c d e f ]

copy set 2 to new area
In new area: [ g h i j k l ]

free()'ing memory

示例代码C

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

typedef char(Target)[2][3];
int print_set(Target*, const char*);

int main(void)
{
    Target set_1 = {{'a', 'b', 'c'}, {'d', 'e', 'f'}};
    Target set_2 = {{'g', 'h', 'i'}, {'j', 'k', 'l'}};

    print_set(&set_1, "Set 1");
    print_set(&set_2, "Set 2");

    printf("\nallocating new area for matrix\n");
    Target* pTarget = (Target*)malloc(sizeof(Target));

    printf("\ncopy set 1 to new area\n");
    memcpy(pTarget, set_1, sizeof(Target));
    print_set(pTarget, "In new area:");

    printf("\ncopy set 2 to new area\n");
    memcpy(pTarget, set_2, sizeof(Target));

    memcpy(pTarget, set_2, sizeof(Target));
    print_set(pTarget, "In new area:");
    printf("\nfree()'ing memory\n");
    free(pTarget);
    return 0;
};

int print_set(Target* tgt, const char* title)
{
    if (tgt == NULL) return -1;
    printf("%s [ ", title);
    for (size_t a = 0; a < 2; a += 1)
    {
        for (size_t b = 0; b < 3; b += 1)
            printf("%c ", (*tgt)[a][b]);
    }
    printf("]\n");
    return 0;
}

只是为了可读性。 是如何通过整个区域的一个例子。typedefprint_set()

评论

0赞 gustavo moretto itikawa 7/28/2023
这种方式对我来说效果最好!它更容易实施和缠绕在我的脑海中。非常感谢!
0赞 gustavo moretto itikawa 7/28/2023
矩阵将始终是固定的,因为它只是一个画布,可以直观地表示 2D 空间中的两个点