c - 在 main 外部定义的函数内分配数组
问题描述
我正在尝试在函数内的数组上使用 calloc,但它不起作用。尝试调试时,我发现在函数内部,指针指向分配的内存,但在离开函数时,它再次指向 NULL。尝试了各种变体,但似乎无法找到解决方案。
这是我的代码:
int main(int argc, char *argv[]) {
int *rows = NULL, *solvedRows = NULL;
int **board = NULL, **solvedBoard = NULL;
allocateMemory(dim, &(*rows), &(*board));
allocateMemory(dim, &(*solvedRows), &(*solvedBoard));
}
void allocateMemory(int dim, int** rows, int*** board) {
rows = calloc(dim*dim,sizeof(int));
board = calloc(dim, sizeof(int*));
if (rows == NULL || board == NULL) {
printf("Error: calloc has failed\n");
exit(1);
}
}
需要帮助以了解问题所在以及如何解决问题。
编辑
我试过了:
*rows = calloc(dim*dim,sizeof(int));
*board = calloc(dim, sizeof(int*));
仍然有同样的问题。
也试过:
allocateMemory(dim, &rows, &board);
对于第 4 行和(第 5 行相同)并且 in 编译时出现错误:“错误:从不兼容的指针类型 [-Werror=incompatible-pointer-types] allocateMemory(dim, &rows, &board) 传递 'allocateMemory' 的参数 2 ); ^" 错误:从不兼容的指针类型传递 'allocateMemory' 的参数 3 [-Werror=incompatible-pointer-types] allocateMemory(dim, &rows, &board); ^
编辑
对于遇到此问题并检查此页面的任何人,最后一次尝试实际上是正确的,正如迈克尔在下面回答的那样。该错误是针对相应头文件中的错误,并且在修复头文件时已修复。
解决方案
让我们关注您的rows
变量:
rows
是一个指针,它是一个保存内存地址的变量。现在您希望 alocateMemory 写入rows
一块内存的地址,以保存您的数据。很简单:
size_d dim = 10;
int* rows = 0;
rows = calloc(1, sizeof(int) * dim);
但是,如果您将此代码放入类似的函数中
void allocateMemory(size_t dim, int* rows) {
rows = calloc(1, sizeof(int) * dim);
}
现在,如果您像这样调用此函数
int* actualRows = 0;
allocateMemory(3, actualRows);
(即)的值将被复制到您在其中操作的新变量中。当你写入行时,它的值会发生变化,但是当你离开时,就会被销毁。永远不会改变。actualRows
0
rows
allocateMemory
allocateMemory
rows
actualRows
你想要的是allocateMemory
设置actualRows
oa 内存地址的值。为此,您必须提供类似allocateMemory
的地址actualRows
allocateMemory(3, &actualRows);
&atualRows
是的内存地址,actualRows
它的类型是int**
(指向指针的指针int
)。
现在您必须allocateMemory
适当地调整签名:
void allocateMemory(size_t dim, int** rows) {
rows = calloc(1, sizeof(int) * dim);
}
而且,由于 rows 现在是一个指针并且您想要更改其目标,因此您需要在分配它之前取消引用它:
*rows = calloc(1, sizeof(int) * dim);
总归:
void allocateMemory(size_t dim, int** rows) {
*rows = calloc(1, sizeof(int) * dim);
}
...
int* actualRows = 0;
allocateMemory(3, &actualRows);
...
对于你board
的,原则上是一样的。尝试
#include <stdio.h>
#include <stdlib.h>
void allocateMemory(int dim, int** rows, int*** board) {
*rows = calloc(dim * dim,sizeof(int));
*board = calloc(dim, dim * sizeof(int*));
if (rows == NULL || board == NULL) {
printf("Error: calloc has failed\n");
}
for(size_t i = 0; i < dim; ++i) {
(*board)[i] = calloc(1, sizeof(int) * dim);
if ((*board)[i] == NULL) {
printf("Error: calloc has failed\n");
}
}
}
int main(int argc, char *argv[]) {
size_t dim = 10;
int *rows = NULL;
int **board = NULL;
allocateMemory(dim, &rows, &board);
rows[0] = 10;
rows[1] = 11;
for(size_t i = 0; i < dim; ++i) {
printf("%i ", rows[i]);
}
printf("\n\n\n");
board[0][0] = 11;
board[9][0] = 99;
board[9][9] = 101;
for(size_t i = 0; i < dim; ++i) {
for(size_t k = 0; k < dim; ++k) {
printf("%i ", board[i][k]);
}
printf("\n");
}
printf("\n");
for(size_t i = 0; i < dim; ++i) free(board[i]);
free(board);
free(rows);
}
推荐阅读
- javascript - 如何制作在更改状态时不会修改所有元素的地图 - React
- java - 连接 Redis 服务器时出现 java.lang.NoSuchFieldError: WRITE_BUFFER_HIGH_WATER_MARK 异常
- primefaces - Primefaces 数据表显示奇怪的字符(例如:'<' 显示为 '<')
- prestashop - Prestashop 搜索仅准确显示
- android - 如何使用隐式意图但避免“选择一个应用程序来处理此意图”屏幕?
- gradle - 使用私有 git 存储库的 Gradle 源依赖项
- c# - 如何防止多线程应用中List引起的InvalidOperationException?
- ajax - 即使在 Flask 应用程序中启用了 CORS,也没有设置 Cookie
- node.js - 如何在我的 schema.graphql 文件中为按 id 过滤的查询引用生成的 Prisma 模式
- angular - 如何通过改变主题来改变背景?