如何分配大小等于从输入文件读取的变量的内存?

How to allocate memory equal in size to a variable read from an input file?

我正在为我的博士学位构建一个代码来模拟一些动力系统的响应。基本上我想做的是:

  1. 要求用户提供包含所有模拟参数的输入文件的名称;
  2. 读取输入文件并将每个参数分配给我程序中的特定变量。
  3. 做计算。

我在步骤 2 中遇到问题,因为输入文件中的值之一是动态分配数组 *x.

的维度 dim

这是代码的一个工作示例:

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

void read_file(char *name, int *dim, double **x) {
    // Open input file
    FILE *input = fopen(name, "r");
    if (input == NULL) {
        // Return error 
        perror(name);
        return;
    }
    // Read and assign system constants
    fscanf(input, "%i", dim);
    printf("dim = %i\n", *dim);
    // Allocate memory for x[dim]
    *x = malloc((*dim) * sizeof(*x));
    double y[(*dim)]; 
    printf("size of (*x) = %llu\n", sizeof(*x));
    printf("size of y = %llu\n", sizeof(y));
    // Security check for pointers
    if(*x == NULL) {
        free(*x);
        printf("Memory allocation for *x did not complete successfully\n");
        return;
    }
    // assign values to x[dim] vector
    for (int i = 0; i < *dim; i++) {
        fscanf(input, "%lf", &(*x)[i]);
        printf("(*x)[%i] = %lf\n", i, (*x)[i]);
    }
    // Close input file
    fclose(input);
}

char *get_input_filename(void) {
    char *filename = malloc(200 * sizeof(*filename));
    printf("Enter Input Filename: ");
    scanf("%s", filename);
    return filename;
}

int main (void) {

    int DIM;
    double *x = NULL;
    
    char *input_filename = get_input_filename();
    read_file(input_filename, &DIM, &x);

    printf("size of (*x) = %llu\n", sizeof(*x));
    for (int i = 0; i < DIM; i++) {
        printf("(*x)[%i] = %lf\n", i, x[i]);
    }

    free(x); free(input_filename);
}

这里是这个例子的输入文件 in.txt 的内容:

5
0.0 0.1 0.2 1.4 2.6

当我调用 *x = malloc((*dim) * sizeof(*x)); 时,我希望找到系统的维度 5 * 8bytes,因为 *dim 的值在上一行中分配,但是只有 8 bytes 被分配。然后,我声明了 y[(*dim)] 变量来检查 sizeofVLA 的行为是否与 sizeof *x 的行为相同,只是为了比较。 sizeof(y) 是我所期望的,但 sizeof(*x) 不是,如输出所示:

Enter Input Filename: in.txt
dim = 5
size of (*x) = 8
size of y = 40
(*x)[0] = 0.000000
(*x)[1] = 0.100000
(*x)[2] = 0.200000
(*x)[3] = 1.400000
(*x)[4] = 2.600000
size of (*x) = 8
(*x)[0] = 0.000000
(*x)[1] = 0.100000
(*x)[2] = 0.200000
(*x)[3] = 1.400000
(*x)[4] = 2.600000

我知道如果*dim的值是未知的,它不能分配内存,但是在上一行赋值了。

此外,我什至不知道程序是如何成功地为 (*x) 赋值的,因为它没有必要的字节分配来完成它。

我在这里错过了什么?如何正确分配内存?

提前致谢

dimx都是输出参数;指向存储此函数结果的位置的指针(double 值的大小和内存分配序列)。

这就是事情进展的地方 rails:

*x = malloc((*dim) * sizeof(*x));

左边没问题。右侧的 most 也是如此。但是如果你曾经根据指针指向的取消引用数据的大小分配给一个指针,你需要这样做:指针指向的东西的大小。 x是一个pointer-to-pointer,*x是一个指针,而后者是我们分配内存的'thing',其地址将存储在 *x.

因此,应该是:

*x = malloc((*dim) * sizeof **x);

注意:当我使用 variables 作为 sizeof 的运算符参数时,我个人努力 not 使用 parens .它确保我实际上使用的是变量 id 而不是类型 id,因为后者在没有括号的情况下是不允许的。在 discretion/whim.

中使用您喜欢的东西

然而更根本的是,你对sizeof的熟悉和理解是错误的and/or误导。您无法使用 sizeof 获取 dynamic-allocated 内存区域的大小。在指针变量上使用 sizeof 运算符将为您提供 完全 您所要求的:指针变量的大小(例如指针的大小)。 有责任维护和跟踪动态分配的大小(顺便说一句,您的代码会使用 dim)。