0

I copy the bytes of a file into a vector of chars. This works if the file is small, but if the file is too big, I get a heap-buffer overflow. I am trying to assert that the file size is less than a std::vector::max_size().

I have something a long the lines of:

#include <iostream>
#include <fstream>
#include <cassert>
#include <vector>

std::vector<char> read_file(const std::string& file_name) {
    // Creats an ifstream object and opens the file given by the argument 'file_name'
    // Opens in binary mode so that there are no misinterpretation of bytes
    // std::ios::ate changes the seek pointer to the end of the file
    std::ifstream input_file(file_name, std::ios::binary | std::ios::ate);
    // Returns the seek pointer of the file
    // The seek points to the end of the file because of 'std::ios::ate'
    std::ifstream::pos_type position { input_file.tellg() };

    // Checks to see if the file (lang: [file]) is too big
    // I cannot compare successfully
    assert(position >= byte_array.max_size());

    // Create the vector we wish to return
    // We need to cast so that the program compiles
    std::vector<char> result ( static_cast<unsigned char>(position) ); 

    // Change the seek pointer to the beginning
    input_file.seekg(0, std::ios::beg);

    // Am trying to copy all the bytes from from the the file into the 
    // vector named return
    input_file.read(reinterpret_cast<char *>(result.data()), position);
    return  result; 
}

int main() {
    read_file("some_file.txt");

    return 0;
}

As of now, the following line does not work:

assert(position >= byte_array.max_size());

How do I compare std::pos_type (which is std::fpos I think) and unsigned int?

Happy Jerry
  • 164
  • 1
  • 8
  • 1
    Seems like a bit of an XY problem. What are you actually trying to solve? – Retired Ninja Aug 01 '22 at 02:38
  • @RetiredNinja have a file and copy all the bytes of the file into a `std::vector` using the code in the OP. If the file is too big AKA if the last position is greater than the maximum size of the vector, I abort the program. As of now, I can't compare `position` and `vector.max_size()` and so I asked here – Happy Jerry Aug 01 '22 at 02:49
  • 1
    The code is too minimal. `std` is not defined, nor is `std::pos_type`. And that assert can't appear in global scope. – Pete Becker Aug 01 '22 at 02:49
  • @PeteBecker The code is now a minimal example. – Happy Jerry Aug 01 '22 at 03:01
  • 1
    From a theory perspective the file position is a signed type of some width and the size_type of a vector is an unsigned type of the same width, so the maximum size of a vector would be larger than the maximum size of a file. In practice you'll run out of RAM before any of this becomes an issue, and checking against the max size isn't a guarantee that a vector of that size can be allocated. – Retired Ninja Aug 01 '22 at 03:03
  • 1
    @HappyJerry "*have a file and copy all the bytes of the file into a `std::vector`*" - related: [How do I read an entire file into a std::string in C++?](https://stackoverflow.com/questions/116038) – Remy Lebeau Aug 01 '22 at 03:06
  • `position >= byte_array.max_size()` --- this makes no sense. First, you have your comparison backwards. Second, `vector::max_size()` cannot be used to check that the vector will fit into available memory. It is typically far, far bigger than anything that will fit. – n. m. could be an AI Aug 01 '22 at 03:43
  • @n.1.8e9-where's-my-sharem. Silly mistake on my part. Fixed now. Is there a way to dynamically check the size so that the I don't run into a buff overflow? – Happy Jerry Aug 01 '22 at 03:47
  • Buffer overflow ia when you access more than you allocate. You are not trying to protect against that. You are trying to protect against memory exhaustion (allocating more than you have). These attempts never work. Just go ahead and allocate. If there is not enough memory, you will get an exception which you can handle – n. m. could be an AI Aug 01 '22 at 04:47

0 Answers0