c - 数组元素在函数外是 "lost"

标签 c pointers malloc realloc

我在文件中有一个矩阵,例如:

3
1 2 3
4 5 6
7 8 -9

其中第一行表示方阵阶数。我正在使用以下代码读取文件并将其存储到 vector 中(为了简单起见,我删除了所有 if 检查):

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

int read_matrix_file(const char *fname, double *vector)
{
    /* Try to open file */
    FILE *fd = fopen(fname, "r");
    char line[BUFSIZ];
    fgets(line, sizeof line, fd);

    int n;
    sscanf(line, "%d", &n)

    vector = realloc(vector, n * n * sizeof *vector);
    memset(vector, 0, n * n * sizeof *vector);

    /* Reads the elements */
    int b;
    for(int i=0; i < n; i++) {
        // Read the i-th line into line
        if (fgets(line, sizeof line, fd) == NULL) {
            perror("fgets");
            return(-1);
        }

        /* Reads th j-th element of i-th line into the vector */
        char *elem_ptr = line;
        for (int j=0; j < n; j++) {
            if(sscanf(elem_ptr, "%lf%n", &vector[n*i+j] , &b) != 1) {
                perror("sscanf");
                return(1);
            }
            elem_ptr += b;
        }
    }
    fclose(fd);

    /* HERE PRINTS OK */
    for(int i=0; i<n*n; i++)
        printf("%i %f\n",i, vector[i]);

    return n;
}

read_matrix_file 接收一个文件名和一个 array doubles 并填充数组,返回矩阵顺序。可以在此代码块中看到预期的用法。

int main(void)
{

    const char *fname = "matrix.txt";
    double *vector = malloc(sizeof * vector);

    int n = read_matrix_file(fname, vector);

    /* Here prints junk */
    for(int i=0; i<n*n; i++)
        printf("%i %f\n",i, vector[i]);

    free(vector);
}

问题是,printfread_matrix_file 中工作正常,但在 main 中似乎无效。

我在函数外部分配数组并通过“引用”传递它,但我非常怀疑 realloc,不幸的是我不知道如何修复或更好的方法。

最佳答案

您正在 read_matrix_file() 中重新分配内存并将矩阵的元素存储在该内存区域中。但是当你从函数中出来时,由于指针 vector 是一个局部变量,当你离开函数时它的新值就丢失了。

当您返回 main() 时,vector 仍然指向您之前使用 malloc() 分配的(现在可能无效的)内存区域。

您应该在调用 read_matrix_file 之前分配足够大的内存,或者如果您想修改指针并在 main()< 中看到更改反射(reflect)回来,则传递一个双指针 (**)/

我的意思是这样的:

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

int read_matrix_file(const char *fname, double **p_vector)
{
    /* Try to open file */
    FILE *fd = fopen(fname, "r");
    char line[BUFSIZ];
    fgets(line, sizeof line, fd);

    int n;
    sscanf(line, "%d", &n);

    *p_vector = realloc(*p_vector, n * n * sizeof **p_vector);
    double *vector = *p_vector;

    memset(vector, 0, n * n * sizeof *vector);

    /* Reads the elements */
    int b;
    for(int i=0; i < n; i++) {
        // Read the i-th line into line
        if (fgets(line, sizeof line, fd) == NULL) {
            perror("fgets");
            return(-1);
        }

        /* Reads th j-th element of i-th line into the vector */
        char *elem_ptr = line;
        for (int j=0; j < n; j++) {
            if(sscanf(elem_ptr, "%lf%n", &vector[n*i+j] , &b) != 1) {
                perror("sscanf");
                return(1);
            }
            elem_ptr += b;
        }
    }
    fclose(fd);

    /* HERE PRINTS OK */
    for(int i=0; i<n*n; i++)
        printf("%i %f\n",i, vector[i]);

    return n;
}

在 main 中,调用它:

int n = read_matrix_file(fname, &vector);

编辑:请注意,此代码无法正确处理 realloc() 的失败。

关于c - 数组元素在函数外是 "lost",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57783557/

相关文章:

c - 将字符串数组从函数传递到主函数(C 代码)

c - 分配给结构的不兼容指针类型

c - 是否可以更改 va_arg 的值?

crash - 如何解决 malloc 崩溃问题

c - 分配失败时释放多维数组

创建带有调试选项的 makefile

python - python ctypes中的未知数组长度

c - 指向 NULL 的指针的 Sizeof()

C++ 程序已停止工作

c - 使用断言处理错误检查