Urasam
Urasam

Reputation: 179

Using streamsize for the size of an array is not working

I somehow can't get it right to use std::streamsize to create an array.

// determine file size
file.ignore(std::numeric_limits<std::streamsize>::max());
std::streamsize length = file.gcount();
file.clear();
file.seekg(0, std::ios_base::beg);

// read data into buffer
std::array<char, length> buffer;
file.read(buffer.data(), length);

// copy the game into memory
std::copy(buffer.begin(), buffer.end(), memory.begin() + 0x200);

Error (translated from German)

The expression must be a constant value

Does anyone have any ideas on solving this problem? Any help is appreciated!

Upvotes: 0

Views: 294

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 596166

You don't need to use file.ignore(), you can use file.seekg() to get the file size:

// determine file size
file.seekg(0, std::ios_base::end);
std::streamsize length = file.tellg();
file.seekg(0, std::ios_base::beg);

Or, just use a platform-specific API function, like GetFileSize() on Windows or stat() on Linux (or equivilents).

That said, std::array is a fixed-length array, you have to specify its size at compile-time. For dynamic allocations at runtime, use std::vector instead:

// read data into buffer
std::vector<char> buffer;
buffer.resize(length);
file.read(buffer.data(), length);

Or, simply read the file into the target memory directly and avoid the temp buffer altogether:

// read game file into memory
file.read(memory.begin() + 0x200, length);

Or, even skip retrieving the file size at all:

// read game file into memory
std::copy(
    std::istreambuf_iterator<char>(file),
    std::istreambuf_iterator<char>(),
    memory.begin() + 0x200
);

In any case, be sure to watch out for memory overflows! Make sure memory is large enough to hold the entire file data.

Upvotes: 2

Matteo Italia
Matteo Italia

Reputation: 126787

You can only pass constexpr values as template parameters, which clearly isn't possible in this case given that the size is known only at runtime.

The underlying problem here is that you are using the wrong tool for the job: std::array encapsulates a statically allocated array, whose size must be known at compile time. If you need dynamic allocation, use std::vector.

For a more in-depth comparison between std::vector and std::array see std::vector versus std::array in C++

Upvotes: 3

Related Questions