当我将 fread 与 34 mb .mp4 文件一起使用时,我遇到了分段错误,我该如何解决?

When I use fread with a 34 mb .mp4 file I get a segmentation fault, how can I solve it?

提问人:DEV 提问时间:10/26/2023 最后编辑:wohlstadDEV 更新时间:10/26/2023 访问量:59

问:

我正在尝试编写可以反转文件以使其不可读的代码。我在 Python 中这样做了,我正在尝试在 C 中再次这样做,但是当我使用 fread 读取大文件时,我遇到了分段错误(对于 1 或 2 mb 的文件,这不会发生),我能做些什么来解决这个问题吗?

我尝试了以下代码:

#include <stdio.h>
#include <conio.h>

int main()
{
    FILE *fh=fopen("vid.mp4","rb");
    FILE *fh1=fopen("vid1.png","wb");

    int fsize=36886031;
    char data[fsize];

    fread(data,fsize,1,fh); //<-- error
    fwrite(data,fsize,1,fh1); //<-- error too
}

我得到:

分段故障 [程序完成]

C 文件 分段 - 故障 读取

评论

0赞 pmg 10/26/2023
char data[fsize]; ==> char *data = malloc(fsize); if (!data) { exit(EXIT_FAILURE); }...并记住当您不再需要它时。free(data)
0赞 Gerhardh 10/26/2023
可能不是您的问题,但您忘记在传递指针之前验证文件是否可以成功打开。fread
1赞 Gerhardh 10/26/2023
在 C 语言中,局部变量通常(未由标准定义)位于堆栈上,其大小仅为几 MB。具体大小取决于操作系统和设置。一个 34MB 的数组对于您的堆栈来说很可能太大,导致堆栈溢出错误。解决方案就是上面提到的pmg。
0赞 Raymond Chen 10/26/2023
这回答了你的问题吗?大容量阵列上的分段故障

答:

1赞 Nierusek 10/26/2023 #1

当您在这样的函数中声明一个变量时,您是在堆栈上声明它。它足够大,可以容纳很多普通变量,但它通常没有足够的内存来容纳大数组。如果要存储大对象,则必须使用 .malloc

在这里,我修改了您的代码,使其不会崩溃。

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

int main() {
    FILE *fh=fopen("vid.mp4","rb");
    size_t fsize = 36886031;
    char *data = malloc(fsize);
    if (data == NULL) {
        fprintf(stderr, "Not enough memory");
        return EXIT_FAILURE;
    }

    fread(data, fsize, 1, fh);
    free(data); // Don't forget to free this memory
    return EXIT_SUCCESS;
}

我强烈建议您阅读有关动态内存分配的文章,因为它是 C 语言中非常重要的一部分。

评论

1赞 pmg 10/26/2023
不@DEV,这种修改是不必要的。确保您的编译器已正确配置:#ifdef __cplusplus / #error bad compiler / #endif
0赞 DEV 10/26/2023
@pmg 是的,我看了一下,发现只需使用typecast
0赞 DEV 10/26/2023
只需做:char *data=(char*)malloc(fsize);
0赞 DEV 10/26/2023
我是新手
0赞 Nierusek 10/26/2023
@DEV 在 C 语言中,强制转换是一种不好的做法。这里有一个链接解释了原因:stackoverflow.com/questions/605845/......malloc