fread, longs and cheap PCs

This is a discussion on fread, longs and cheap PCs within the C Programming forums, part of the General Programming Boards category; Hi, I've been trying to load a file into memory, using the following code:- Code: long fsize(FILE *fp) { long ...

  1. #1
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,266

    Angry fread, longs and cheap PCs

    Hi,

    I've been trying to load a file into memory, using the following code:-

    Code:
    long fsize(FILE *fp)
    {
       long pos, size;
    
       pos = ftell(fp);
       fseek(fp, 0, SEEK_END);
       size = ftell(fp);
       fseek(fp, pos, SEEK_SET);
       return size;
    }
    
    int main(void)
    {
       unsigned char *temp;
       long filesize;
       FILE *fp;
    
       fp = fopen("data.dat", "rb");
       filesize = fsize(fp);
       temp = (unsigned char *)malloc(filesize);
       if (temp == NULL)
       {
          printf("Memory allocation error\n");
          return -1;
       }
       fread(temp, filesize, 1, fp);
       return 0;
    }
    However, when I compile this with Borland Turbo C 2.0, using a large memory model and then run it, it crashes (and on these cheap Cyrix MX/S3 Virge-based PCs my school uses, the screen messes up completely...).
    It seems that temp is allocated correctly (malloc doesn't return NULL), but the fread statement is causing bother. The fact that I'm using a long for filesize when size_t is defined as an unsigned int (max 65,535) is concerning, but as the file I'm testing it on is only 48,200 bytes, it shouldn't overflow upon truncation, should it?

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    On many systems fread best reads from binary files, doesn't it?

    Perhaps shift the opening and closing of this file into the function, use fgets and concat to temp. Have the function return the allocated memory.


    Code:
    char *func(char *filename)
    {
    //file pointer
    //fopen(filename, "r");
    //*buf
    //return NULL string if error
    //size == ...
    //buf = malloc(sizeof(char) *size);
    //while(!feof(fp))
    //fgets()
    //strcat()
    
    buf[strlen(buf)- 1] = '0';
    
    return buf;
    }
    
    
    //main
    
    char *contents = func("data.txt");
    
    printf("%s", contents);
    
    free(contents);
    
    //return 0
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,266

    Question

    Eh?

    The file is binary, so using text read functions to read it is just gonna make things even more complicated (bumping into control codes all over the place, etc.). You ever tried printfing an image? 'Tis well ugly.

  4. #4
    Unregistered
    Guest
    Well then I was off the mark then-wasn't I?

    Why are you are freading binaries into an unsigned char pointer?

    Is this conventional? Why not to a struct or something?

  5. #5
    Registered User alex's Avatar
    Join Date
    Sep 2001
    Posts
    132
    Does it work with the huge memory model?

    alex

  6. #6
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,266
    I think I'd better clear things up a bit...

    I'm loading a big chunk of RLE-encoded image data into memory so I can quickly reconstruct the original image and display. I'm currently doing it so that each individual byte is read from the hard drive and dealt with, but that takes ages, so I'm trying to put it temporarily into memory, decode the information into a separate buffer, and deallocate the memory containing the RLE data. Sorry for any confusion.
    Last edited by SMurf; 12-13-2001 at 02:39 PM.

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Have you tried using a 'far' pointer? Since you're using a 16bit compiler, you may be beyond what a 'near' pointer is able to handle. Honestly, I've never had occasion to use them (I'd really suggest getting a new compiler. There are some good free ones!) but I believe you want something like:

    unsigned char far *buf;

    Note: Far pointers are obsoleted with 32bit compilers.

    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Registered User alex's Avatar
    Join Date
    Sep 2001
    Posts
    132
    If you use far pointers, you should also allocate the memory in a separate segment (my guess: farmalloc). You said that reading data from file byte per byte was very slow... Maybe you're better off reading the file in small segments of a few Kb. A second guess of mine: you are using the BGI library to draw? This is very slow if you use putpixel to draw one pixel at a time!

    alex

  9. #9
    Ultra3e
    Guest

    Red face

    { printf int main (int argc, char **argv)
    {
    struct stat stat;
    void *mem = (void *) NULL;
    int fd;

    if (stat("fullpath/filename", &stat != -1)
    {
    if ( mem = malloc ((size_t) stat.st_size) != NULL)
    {
    if ((fd = open("fullpath/filename", O_RDONLY )) != -1)
    {
    read(fd, mem, (size_t)stat.st_size);
    close(fd);
    ..... do your own code
    free(mem);
    }
    }
    }
    else
    ("File not found\n");
    }
    return(0);
    }

    Note : Use Unix and mmap the file, ist easier and much faster,
    If Your file is bigger than 64K data segment, use
    huge memory model and far pointers.

  10. #10
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    So how are these RLE-encodings stored as unsigned chars?

    And why not decode it while you read it in to storage, bit by bit?
    Last edited by Sebastiani; 12-14-2001 at 01:08 PM.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  11. #11
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,266
    I USED to decode them into storage from disk, but like I said, it takes ages, so I'm trying to stick it in memory first THEN decode it and free the encoded data, which should give me much faster processing. The RLE is PCX-style (> 0xC0 (192) for a run, then the pixel value for it in the next byte).

    And I thought compiling in the large memory model meant that data pointers were far by default?

  12. #12
    Registered User
    Join Date
    Dec 2001
    Posts
    5

    Re: fread, longs and cheap PCs

    There might be other problems . . . like some error checking that isn't being done, etc., but one thing that you'll need to do is change:

    fread(temp, filesize, 1, fp);

    to

    fread(temp, (size_t)filesize, (size_t)1, fp);


    Hope This Helps,
    Joshua Burkholder

  13. #13
    Linguistic Engineer... doubleanti's Avatar
    Join Date
    Aug 2001
    Location
    CA
    Posts
    2,459
    as an alternative file length derivation, use this and maybe it'll work out...

    Code:
    #include <io.h>  //  fileno ()
    #include <stdio.h>  //  filelength ()
    size = filelength ( fileno (fp) );
    hasafraggin shizigishin oppashigger...

Popular pages Recent additions subscribe to a feed

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21