使用“malloc”在函数中定义一个数组,并返回该数组,从而导致分段错误

Used `malloc` to define an array inside a function and returning that array giving segmentation fault

提问人:altair00 提问时间:3/17/2023 最后编辑:chqrliealtair00 更新时间:3/17/2023 访问量:37

问:

我正在尝试从进程 .txt 获取输入。因此,我创建了一个函数来从该文件中获取这些输入。

进程.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)

阵列 C 分段-故障 malloc

评论


答:

1赞 Harith 3/17/2023 #1
 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);

分段错误也可能源于从指针读取,因为 的返回值已传递给 unchecked。NULLfopen()fscanf()

如果调用失败,后续操作将是读取/写入指针,这将调用未定义的行为。fopen()NULL

if (!fopen ("process.txt", "r")) {
    perror ("fopen()");
    complain ();
}

malloc()同样,返回以指示失败。应该对它进行类似的检查。NULL

1赞 chqrlie 3/17/2023 #2

关于是否使用其值或地址存在一些混淆,这导致您将其定义为指针。应定义为类型为 的整数。并将其地址传递给 。lenlen&lenlenintfscanf()

这是修改后的版本:

#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;
}