在内存中动态分配矩阵时的问题
Problems when dynamically allocating a matrix in memory
如果标题在这个问题上不够具体,我很抱歉,但我遇到了一些关于双指针的非常奇怪和不一致的问题,我不知道如何用一句话来描述它们。
基本上,每次我的程序运行时,它都会分配一个大小随机生成的矩阵。
coord mapSize;
mapSize.row = randomRange(3, 5);
mapSize.column = randomRange(5, 7);
char** map = (char**) malloc (mapSize.row * sizeof(char));
for (int i = 0; i < mapSize.row; i++)
{
map[i] = (char*) malloc (mapSize.column * sizeof(char));
}
然后矩阵被初始化:
for (int i = 0; i < mapSize.row; i++)
{
for (int j = 0; j < mapSize.column; j++)
{
map[i][j] = CLEAN_FLOOR_SYMBOL;
}
}
只要矩阵的大小不超过 4 行,此方法就可以完美运行。如果发生这种情况,程序只会在初始化到达第五行时崩溃。更奇怪的是,即使行数大于5,初始化到第5行还是出现问题
我已经通过在初始化循环中打印出一些值来验证这一点。
printf("r: %d c: %d\n\n", mapSize.row, mapSize.column);
for (int i = 0; i < mapSize.row; i++)
{
printf("r: %d | c: ", i);
for (int j = 0; j < mapSize.column; j++)
{
map[i][j] = CLEAN_FLOOR_SYMBOL;
printf("%d ", j);
}
printf("\n");
}
这里有 6 行,但是在尝试初始化第五行时程序仍然崩溃。
更奇怪的是 none 这些问题似乎是在 运行 eclipse 控制台上的程序时出现的。那么,我怎么搞砸了?
在
char** map = (char**) malloc (mapSize.row * sizeof(char));
您缺少 *
,请 don't cast the result of *alloc()
*):
char **map = malloc (mapSize.row * sizeof(char*));
// ^
// here
更好:
char **map = malloc (mapSize.row * sizeof(*map));
因为这里的类型大小是随着 map
类型的变化而改变的,所以如果它应该改变,你不必记住在多个地方改变类型。
如果您想要性能,请去掉 **
。查看什么是锯齿状数组并避免它:
size_t num_rows = // ...
size_t num_cols = // ...
char *foo = malloc(num_rows * num_cols * sizeof *foo);
// access:
size_t row = // ...
size_t col = // ...
foo[row * num_rows + col];
*) 如果您的编译器抱怨您正在使用 C++ 编译器编译 C 代码。
如果标题在这个问题上不够具体,我很抱歉,但我遇到了一些关于双指针的非常奇怪和不一致的问题,我不知道如何用一句话来描述它们。
基本上,每次我的程序运行时,它都会分配一个大小随机生成的矩阵。
coord mapSize;
mapSize.row = randomRange(3, 5);
mapSize.column = randomRange(5, 7);
char** map = (char**) malloc (mapSize.row * sizeof(char));
for (int i = 0; i < mapSize.row; i++)
{
map[i] = (char*) malloc (mapSize.column * sizeof(char));
}
然后矩阵被初始化:
for (int i = 0; i < mapSize.row; i++)
{
for (int j = 0; j < mapSize.column; j++)
{
map[i][j] = CLEAN_FLOOR_SYMBOL;
}
}
只要矩阵的大小不超过 4 行,此方法就可以完美运行。如果发生这种情况,程序只会在初始化到达第五行时崩溃。更奇怪的是,即使行数大于5,初始化到第5行还是出现问题
我已经通过在初始化循环中打印出一些值来验证这一点。
printf("r: %d c: %d\n\n", mapSize.row, mapSize.column);
for (int i = 0; i < mapSize.row; i++)
{
printf("r: %d | c: ", i);
for (int j = 0; j < mapSize.column; j++)
{
map[i][j] = CLEAN_FLOOR_SYMBOL;
printf("%d ", j);
}
printf("\n");
}
这里有 6 行,但是在尝试初始化第五行时程序仍然崩溃。
更奇怪的是 none 这些问题似乎是在 运行 eclipse 控制台上的程序时出现的。那么,我怎么搞砸了?
在
char** map = (char**) malloc (mapSize.row * sizeof(char));
您缺少 *
,请 don't cast the result of *alloc()
*):
char **map = malloc (mapSize.row * sizeof(char*));
// ^
// here
更好:
char **map = malloc (mapSize.row * sizeof(*map));
因为这里的类型大小是随着 map
类型的变化而改变的,所以如果它应该改变,你不必记住在多个地方改变类型。
如果您想要性能,请去掉 **
。查看什么是锯齿状数组并避免它:
size_t num_rows = // ...
size_t num_cols = // ...
char *foo = malloc(num_rows * num_cols * sizeof *foo);
// access:
size_t row = // ...
size_t col = // ...
foo[row * num_rows + col];
*) 如果您的编译器抱怨您正在使用 C++ 编译器编译 C 代码。