C语言如何根据输入文件读取的变量值正确分配对应大小内存
核心问题说明
你遇到的问题本质是几个C语言的认知误区,和dim值是否提前读取没有关系:
sizeof无法获取malloc实际分配的内存大小sizeof是编译期运算符(仅对变长数组VLA例外),它只会根据传入表达式的静态类型计算大小,完全不会追踪运行时动态分配的内存长度。
你代码中read_file函数的形参x类型是double**,因此函数内的*x静态类型是double*(指向double的指针),在64位系统下指针的固定大小是8字节,所以不管你malloc分配了多大内存,函数内sizeof(*x)永远返回8,这和实际分配的内存长度无关。另外你在main函数中直接定义的x类型是double*,那里的*x类型是double,sizeof(*x)返回的8是单个double元素的大小,同样不是整个动态数组的总长度。
你声明的VLA数组y之所以sizeof(y)返回40,是因为C标准对VLA做了特殊处理:对VLA使用sizeof时会在运行时计算整个数组的实际占用长度,这是唯一的例外场景,动态分配的指针不适用这个规则。- 你误以为自己只分配了8字节内存,当前64位环境下分配大小正确只是巧合
你写的分配语句*x = malloc((*dim) * sizeof(*x));中,sizeof(*x)计算结果是8,传入malloc的实际参数是5*8=40字节,刚好和存储5个double类型需要的40字节相等,所以分配大小是符合预期的,你看到的8只是sizeof返回的指针本身大小,不是分配的总内存长度。
但这个写法存在严重的移植性问题:如果在32位系统下编译,指针大小是4字节,这时候传入malloc的大小就会变成5*4=20字节,不足以存储5个double,必然出现内存越界。 - C语言没有内置的内存越界检查
哪怕你真的只分配了8字节内存,后续循环给5个元素赋值的操作属于未定义行为:C不会在运行时检查你访问的内存是否属于已分配的范围,只要你访问的内存地址是可写的,程序就不会立刻崩溃,只是会偷偷破坏内存里的其他数据,可能在后续任意位置触发莫名其妙的bug。你这次测试能正常输出,只是因为越界(如果真的发生的话)的位置刚好没有被其他变量占用,属于运气好,不代表代码是正确的。
修正方法
- 修正
malloc的大小计算逻辑,用数组元素的类型做sizeof计算,避免指针大小带来的错误:
把分配语句改成
这里*x = malloc((*dim) * sizeof(**x));**x的静态类型是double,不管在什么平台下,sizeof(**x)都能正确返回单个double元素的大小,不会受指针长度影响。 - 调整空指针检查的位置,
malloc返回后立刻判断是否分配成功,不要先解引用可能为NULL的指针;同时sizeof返回值类型是size_t,打印时要用%zu格式符,不要用%llu避免跨平台打印错误。 - 不要试图用
sizeof获取动态分配数组的长度,C语言标准库不向用户暴露malloc分配块的长度,如果你需要知道数组长度,要自己保存dim变量的值。
修正后的read_file函数关键部分参考:
// Read and assign system constants fscanf(input, "%i", dim); printf("dim = %i\n", *dim); // Allocate memory for x[dim] *x = malloc((*dim) * sizeof(**x)); // 立刻做空指针检查,避免后续解引用空指针 if(*x == NULL) { printf("Memory allocation for *x did not complete successfully\n"); fclose(input); return; } double y[(*dim)]; printf("size of pointer *x = %zu\n", sizeof(*x)); // 这里永远是指针大小,不要用来判断分配长度 printf("total size of allocated array = %zu\n", (*dim)*sizeof(**x)); // 手动计算分配的总长度 printf("size of VLA y = %zu\n", sizeof(y)); // 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);
内容的提问来源于stack exchange,提问作者Luguecos
相关产品推荐
相关产品推荐

