与对实际文件进行更昂贵的读取相比,我似乎无法将二进制文件加载到内存中以获得更好的读取性能。文件大小为124MB,应该能够完全装入内存。这是用C编写的,由GCC 6.3在84 GNU/Linux上编译。
试图从blk*访问fread时出错。
我试过的两个malloc调用是:

uint8_t *blk = malloc(sizeof(uint8_t) * fileSize + 1);
uint8_t *blk = (uint8_t *) malloc(sizeof(uint8_t) * fileSize + 1);

并检查malloc是否返回NULL,但没有返回。
        FILE *file = fopen("path", "rb");

        fseek(file, 0, SEEK_END);
        long fileSize = ftell(file);

        if (ftell(file) != EOF) {
            printf("Ftell not EOF);
        }

        fseek(file, 0, SEEK_SET);

        uint8_t *blk = malloc(sizeof(uint8_t) * fileSize + 1);

        if (file != NULL) {
            printf("File Not NULL and %d\n", fileSize);
        }
        if (blk) {
            printf("Not NULL\n");
        } else {
            printf("NULL\n");
        }

        fread(blk, 1, fileSize, file);
        fclose(file);

        printf("blk: %p | %d\n", *&blk, blk);

输出为:
    Ftell not EOF
    File Not NULL and 134215964
    blk: 0x7fffffffdcc0 | -9024
    Not NULL
    Segmentation fault

打印格式可能是错误的,但分割错误并不重要。

最佳答案

如果您还没有弄清楚,您的分割错误是由以下原因造成的:

 printf("blk: %p | %d\n", *&blk, blk);

因为您试图将blk(指向uint8_t的指针)打印为整数。参数类型和printf格式说明符之间的不匹配调用未定义的行为。
C11 Standard - 7.21.6.1 The fprintf function(p9)" If a conversion specification is invalid, the behavior is undefined. If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined."
另外请注意,在该语句中使用'*&'之前的blk是多余的。它只是blk。解引用指针的地址只是指针本身。通过使用blk中正确的精确宽度宏,可以更正语句以打印inttypes.h中的指针地址和第一个字节,例如。
printf("blk: %p | 0x%02" PRIx8 "\n", (void*)blk, *blk);

在您的分配中,不需要fileSize + 1,除非您希望使用hack来确定nul terminateblk,以便它可以用作字符串。在某些情况下,它可能很方便,但通常不建议这样做。当ftell返回文件中的字节数时,这就是您需要分配的所有字节数,除非您计划在末尾添加一些内容。而且,sizeof(uint8_t)likesizeof(char)总是1-它也是多余的,例如,
    if (!(blk = malloc (filesize))) {       /* validate allocation */
        perror ("malloc-blk");
        return 1;
    }

此外,WhozCraig试图向您传达,每一步都应该得到验证。通过正确的验证,代码在哪里失败是没有问题的。向每个步骤添加验证类似于:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>

int main (int argc, char **argv) {

    uint8_t *blk;
    long filesize;
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        perror ("file open failed");
        return 1;
    }

    if (fseek (fp, 0, SEEK_END) == -1) {    /* validate seek end */
        perror ("fseek-SEEK_END");
        return 1;
    }
    if ((filesize = ftell (fp)) == -1) {    /* validate ftell */
        perror ("ftell-fp");
        return 1;
    }
    if (fseek (fp, 0, SEEK_SET) == -1) {    /* validate seek set */
        perror ("fseek-SEEK_SET");
        return 1;
    }

    if (!(blk = malloc (filesize))) {       /* validate allocation */
        perror ("malloc-blk");
        return 1;
    }

    if (fread (blk, 1, filesize, fp) != (size_t)filesize) { /* validate read */
        perror ("fread-blk");
        return 1;
    }

    if (fp != stdin) fclose (fp);   /* close file if not stdin */

    /* do what you need with blk here */
    printf("blk: %p | 0x%02" PRIx8 "\n", (void*)blk, *blk);

    free (blk);
}

(注意:使用完后不要忘记free (blk);
示例使用/输出
对任何文件按原样运行代码,只需将blk的指针地址和文件中的第一个字节输出为2位十六进制,例如。
$ ./bin/rdfileintoblk ../dat/captnjack.txt
blk: 0x17e9240 | 0x54

仔细看一下,如果有什么问题请告诉我。

10-07 16:28