gpt4 book ai didi

c - 如何在 C 函数中使用二维数组作为输出参数

转载 作者:太空宇宙 更新时间:2023-11-04 08:10:07 25 4
gpt4 key购买 nike

我正在编写一个程序,使用弗洛伊德算法计算图上两点之间的最短路径。我需要写入一个二进制文件,然后从中读取并打印图表。我的问题就在这里,因为我的函数签名必须采用以下形式:void read_graph(char *filename, int *n, int ***A)

我写了以下内容:

void read_graph(char *filename, int *n, int ***A)
{
FILE *fin;
size_t i;
int x;
int **arr;

fin = fopen(filename, "rb");
if (fin == 0) {
printf("Error opening file\n");
exit(1);
} else {
fread(&x, sizeof(int), 1, fin);
printf("Read size of matrix %d\n",x);
*n = x;
fseek(fin, sizeof(int)+1, SEEK_SET);
arr = malloc(x*sizeof(int *));
if (arr == NULL) {
printf("Not enough space.\n");
}
for (i = 0; i < x; ++i) {
arr = malloc(x*sizeof(int));
}
for (i = 0; i < x; ++i) {
fread(arr,sizeof(int), x, fin);
}

// ***A = **arr;
}
fclose(fin);
free2darray(*A, x);
}

free2darray 是一个释放内存的实用函数。我的问题是,如果我在调用它之前分配一个二维数组,这个函数就可以工作。但是,要求此函数将二维数组返回给 ***A,而不是相反。如果您能告诉我我做错了什么,那将非常有帮助。也欢迎批评代码风格。

编辑:这是我当前调用函数的方式:

int **arr;
int x;
size_t i;
arr = malloc(5*sizeof(int*));
if (arr == NULL) {
printf("Cannot allocated memory for array\n");
exit(1);
}
for (i = 0; i < 5; i++) {
arr[i] = malloc(5*sizeof(int));
}
read_graph("test.dat", &x, &arr);

5 只是一个测试大小。 test.dat 之前是通过使用随机值填充 5*5 数组编写的。

谢谢

最佳答案

你很接近。如果您在几分钟前阅读了我的回答,您可能已经注意到我的解决方案返回了一个指向动态数组的指针。然后我在你的问题的评论中看到函数原型(prototype)是给定的,所以我修改了我的答案。

main() 中您需要做的就是声明一个指向 int 的指针来存储矩阵的大小,以及一个指向指向 的指针的指针int,它将被传递给函数 read_graph()。虽然这不是绝对必要的,但出于良好的风格,我继续将此指针 (arr) 初始化为 NULL。我在这里包含了几行来显示新数组的内容。

您需要在退出前释放分配的内存。这是您在原始代码中遇到的主要问题之一:您在调用 read_graph() 结束时释放了内存。在释放这些分配之前,您需要等到不再需要数组内容。

我发现的另一个问题是,当您为动态数组的各个行分配内存时,您忘记了索引arr,所以您malloced 内存和将地址分配给同一指针 x 次。这是重复将内存重新分配给 arr 的循环(并且是内存泄漏,因为对先前分配的引用丢失了):

for (i = 0; i < x; ++i) {
arr = malloc(x*sizeof(int));
}

传递给函数的指针 A 用于接收调用 malloc() 的结果,以便调用函数可以看到分配的内存.这会稍微改变您的一些分配,因为您最初为此目的在 read_graph() 中声明了一个指针。我还更改了将值读入数组的循环,以便它一次读入一个值——看起来您正试图一次读入 x

您实际上并不需要 fseek(),因为文件指针已经就位,所以我删除了该行。我还添加了一个检查以确保数据文件正确关闭。我制作了一个测试数据文件,一切似乎都有效。我还将您的 size_t 变量更改为 int。我这样做是因为在生成编译器警告的循环中比较了 int 值与 size_t 值。该代码仍然可以正常工作,但是忽略警告是没有意义的。我本来可以将所有内容都更改为 size_t,但是您从文件中读取了矩阵的大小,这在您的代码中是一个 int。如果您可以稍微更改文件格式,矩阵的大小可以存储为 size_t 值。这是修改后的代码:

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

void read_graph(char *filename, int *n, int ***A);
void free2darray(int ***A, int n);

int main(void)
{
int x;
int **arr = NULL;
int i, j;

read_graph("test.dat", &x, &arr);

for (i = 0; i < x; i++) {
for (j = 0; j < x; j++)
printf("%d ", arr[i][j]);
putchar('\n');
}

/* Free allocated memory */
free2darray(&arr, x);

return 0;
}

void read_graph(char *filename, int *n, int ***A)
{
FILE *fin;
int i;
int x;

fin = fopen(filename, "rb");
if (fin == 0) {
printf("Error opening file\n");
exit(1);
} else {
fread(&x, sizeof(int), 1, fin);
printf("Read size of matrix %d\n",x);
*n = x;

*A = malloc(x*sizeof(int *));
if (*A == NULL) {
printf("Not enough space.\n");
}
for (i = 0; i < x; ++i) {
(*A)[i] = malloc(x*sizeof(int));
}
for (i = 0; i < x; ++i)
for (int j = 0; j < x; ++j)
fread(&(*A)[i][j], sizeof(int), 1, fin);
}

if (fclose(fin) != 0)
fprintf(stderr, "Unable to close file\n");
}

void free2darray(int ***A, int n)
{
for (int i = 0; i < n; i++)
free((*A)[i]);
free(*A);
}

编辑

我必须创建一个测试文件,因此我为此添加了一些上面未显示的代码。它读取文本文件并创建程序可以使用的二进制文件。生成的二进制文件只是一个 int 序列。我只是将代码放在 main() 的开头,并在与“a.out”相同的目录中创建了一个名为“testdat.txt”的文件。我的文本文件在第一行包含一个 5,然后是 25 个整数,每行一个:

5
1
2
3
4
5
....

代码如下:

/* Code to create a datafile from a text file */

FILE *fpin, *fpout;
char nstr[100];
int num_out;

fpin = fopen("testdat.txt", "r");
fpout = fopen("test.dat", "wb");
while (fgets(nstr, 100, fpin) != NULL) {
num_out = atoi(nstr);
fwrite(&num_out, sizeof(int), 1, fpout);
}
fclose(fpin);
fclose(fpout);

关于c - 如何在 C 函数中使用二维数组作为输出参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40136902/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com