Search code examples
c++arraysclassmemorycompile-time

How do i make an array which is a class object and has a compile time size?


I'm new at this and haven't done much, but I'm really stuck on making a compile-time sized array, which is a class object. And maybe there's a way to save all the information from file, while occupying less of memory? Here's a bit of my code:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

class Beer
{
public:
    string name;
    string rating;
    string country;
    string alc;
    string type;
};

int main()   //Function uses ''bytes of stack/exceeds analyze:stacksize '16384'. 
             //Consider moving some data to heap
{
    ifstream file("beer.txt");

    if (!file.good())
    {
        cout << "Error. File was not found." << endl;
        exit(EXIT_FAILURE);
    }
    else
    {
        int count;
        string line;
        ifstream file("beer.txt");
        int count = 0;
        for (int i = 0; !file.eof(); i++)
        {
            getline(file, line);
            count++;
        }

        const int SIZE = count;  //<- this is the place i'm struggling with

        Beer allBeers[SIZE];     //expression must have a constant value
        Beer currentBeer;  

        for (int i = 0; !file.eof(); i++)
        {
            getline(file, currentBeer.name, '\t');
            getline(file, currentBeer.rating, '\t');
            getline(file, currentBeer.country, '\t');
            getline(file, currentBeer.alc, '\t');
            getline(file, currentBeer.type, '\n');

            allBeers[i] = currentBeer;
        }


    }
    file.close();
    return 0;
}

Solution

  • The main problem with your code is in the following two lines:

        const int SIZE = count;  //<- this is the place i'm struggling with
        Beer allBeers[SIZE];     //expression must have a constant value
    

    Now, although SIZE is defined as const it is not a compile-time constant! Further, arrays in C++ need dimensions that are compile-time constants. (Your const qualifier means only that, once initialized, the value of SIZE cannot be changed.)

    The simple, "old-style-C++" way of working around this is to declare allBeers as a pointer and use the new operator to create the 'array buffer' at run-time (when the actual value of SIZE is known):

        const int SIZE = count;  // Don't really need this, now - could just use "count"
        Beer* allBeers = new Beer[SIZE]; // You can still use allBeers[i] to access!
    

    But, here, you shoud be sure to execute delete[] allBeers; when you're done with the array/buffer.

    A more modern approach would be to use the std::vector type, in which case freeing memory takes care of itself when the object goes out of scope:

        const size_t SIZE = size_t(count);
        std::vector<Beer> allBeers(SIZE);
    

    Again, you can then access using allBeers[i].

    Feel free to ask for further clarification and/or explanation.