提问人:gustavo moretto itikawa 提问时间:7/26/2023 最后编辑:Vlad from Moscowgustavo moretto itikawa 更新时间:7/26/2023 访问量:65
在 C 语言中二元分配二维矩阵
Dinamically allocating a 2D matrix in C
问:
我正在尝试在 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]
如何继续在内存中分配此矩阵?
答:
不要让它变得困难。使用结构。
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));
不能动态分配已初始化的数组,除非该函数可以按零初始化分配的内存。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] = '#';
}
注意这一点而不是幻数,最好使用命名常量。还要记住,矩阵的元素不包含字符串。8
24
您已经分配了矩阵。只是不是动态的。
鉴于此矩阵在堆栈上的大小并不令人望而却步,因此需要动态分配的唯一原因是,如果您在一个函数中创建它,并且需要它在该函数的生命周期中存活。
你的问题暗示你的问题在于将其传递给函数。当你的矩阵被传递给一个函数时,它会衰减为一个指针,但什么样的指针呢?好吧,它衰减为指向 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);
评论
有很多方法可以写这个。要走的路取决于您将使用该区域的方式。
首先要问的问题是矩阵维度是否始终相同
如果这就是你所需要的,我将向你展示一个更简单的写法的例子。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;
}
只是为了可读性。 是如何通过整个区域的一个例子。typedef
print_set()
评论
上一个:关于动态内存分配的C编程面试题
下一个:越界访问数组有多危险?
评论
calloc
malloc
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; }