我正在尝试从 process.txt 获取输入。所以我做了一个函数来从那个文件中获取这些输入。
process.txt文件的内容:
2
3
4
c
文件:
#include <stdio.h>
#include <stdlib.h>
int *takeInput(int *len) {
FILE *fp = fopen("process.txt", "r");
fscanf(fp, "%d", len);
int *arr = malloc(sizeof(int) * (*len));
for (int i = 0; i < (*len); i++) {
fscanf(fp, "%d", &arr[i]);
}
/* for (int i = 0; i < (*len); i++) { */
/* printf("%d\n", arr[i]); */
/* } */
/* printf("%p\n", arr); */
fclose(fp);
return arr;
}
int main() {
int *len;
int *arr = takeInput(len);
printf("%d\n", *len);
return 0;
}
运行这个程序给了我
Segmentation fault (core dumped)
。
我无法在这里检测到错误。
fscanf(fp, "%d", len);
尝试访问不属于它的内存。
声明一个指针不会为指向的数据分配内存。使用自动存储持续时间声明的未初始化指针的内容是不确定的,即它可能指向内存中的任何内容,并且进程取消引用它是无效的。
这里不需要动态内存分配。只需声明一个具有自动存储持续时间的
int
:
int len = 0;
/* Or better as: */
size_t len = 0; /* It can't be negative. */
并将它的地址传递给函数:
int *arr = take_input (&len);
分段错误也可能源于读取
NULL
指针,因为 fopen()
的返回值未经检查就传递给了 fscanf()
。
如果对
fopen()
的调用返回失败,后续操作将读取/写入NULL
指针,这将调用未定义的行为。
if (!fopen ("process.txt", "r")) {
perror ("fopen()");
complain ();
}
malloc()
也是,返回 NULL
表示失败。应该对其进行类似的检查。
关于
len
是使用它的值 len
还是它的地址 &len
存在一些混淆,这导致您将其定义为指针。您应该将 len
定义为类型为 int
的整数。并将其地址传递给fscanf()
.
这里是修改版:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *takeInput(int *len) {
FILE *fp = fopen("process.txt", "r");
if (fp == NULL) {
fprintf(stderr, "cannot open %s: %s\n",
"process.txt", strerror(errno));
return NULL;
}
if (fscanf(fp, "%d", len) != 1) {
fprintf(stderr, "invalid length\n");
fclose(fp);
return NULL;
}
int *arr = malloc(sizeof(*arr) * (*len));
if (arr == NULL) {
fprintf(stderr, "cannot allocate array\n");
fclose(fp);
return NULL;
}
for (int i = 0; i < (*len); i++) {
if (fscanf(fp, "%d", &arr[i]) != 1)
break;
}
fclose(fp);
return arr;
}
int main(void) {
int len;
int *arr = takeInput(&len);
if (arr != NULL) {
printf("%d\n", len);
for (int i = 0; i < len; i++) {
printf("%d\n", arr[i]);
}
free(arr);
}
return 0;
}