L'array di una struttura richiede parametri "costanti"

di il
4 risposte

L'array di una struttura richiede parametri "costanti"

Buongiorno a tutti,
sto affrontando una difficoltà che molto probabilmente ha una soluzione banale, ma non ne sto venendo a capo :/.

Descrizione del problema:
Sto scrivendo un programma in C++ nel quale ho bisogno di una struttura contenente 3 interi, successivamente devo inizializzare un array di questa struttura, il problema è che le dimensioni dell'array non sono fisse ma possono variare, quindi devo passargli delle variabili, subito il compilatore ha dato errore dicendo che la dimensione dell'array dev'essere definita da un intero costante, ho provveduto a correggere l'errore ma il compilatore non sembra essere d'accordo e non capisco il perché.

struct COLOR
{
	int R;
	int G;
	int B;
};

const int ScreenX = GetSystemMetrics( SM_CXSCREEN );
const int ScreenY = GetSystemMetrics( SM_CYSCREEN );
COLOR schermo[ScreenX][ScreenY];
Risposta del compilatore:
[Error] array bound is not an integer constant before ']' token

Dove sto sbagliando?

Grazie in anticipo!

4 Risposte

  • Re: L'array di una struttura richiede parametri "costanti"

    Se usi le funzioni non puoi usare le costanti.

    Usa delle variabili e l'allocazione dinamica o I vector
  • Re: L'array di una struttura richiede parametri "costanti"

    
    int f() {
        return 5;
    }
    
    int main(int argc, char *argv[])
    {
        // Stack (nota lo stack di solito è 1-8 Mb a seconda del S.O. o anche molto meno)
        int data[f()][f()];
    
        // Heap / dinamica -> Probabilmente nel tuo caso dovresti fare così
        int * dataPointer = new int[f()*f()];
    }
    
    // Allocazione Statica, non possiamo usare f() perchè il valore di f() deve essere definito a "compile time"
    int data[5][5];
    
    constexpr int g() {
        //funzioni constexpr possono chiamare solo cose che a loro volta sono costanti o comunque definibili compile time
        return 5;
    }
    
    // Allocazione Statica, con funzione constexpr
    int data2[g()][g()];
    
    
    
    Ciao.

    Per andare un po' più nel dettaglio devi capire i vari tipi di allocazione della memoria.
    Quando fai un'allocazione statica della memoria come nel tuo caso il compilatore deve sapere a "compile time" lo spazio da allocare.
    Nel tuo caso il valore dipende dalla funzione GetSystemMetrics() e quindi non può essere calcolato finche il programma non è avviato.

    Per aggirare il problema puoi usare un'allocazione che avviene a runtime (dinamica): stack o heap;
    oppure definire la funzione come "constexpr" il che implica che il valore della funzione viene calcolato in fase di compilazione se possibile, ma probabilmente se usi constexpr sposterai solo il problema a qualche altra chiamata.

    Lo stack solitamente è piuttosto limitato, massimo qualche MB di default. Nel tuo caso il sistema migliore sarebbe l'allocazione dinamica dato che occuperai molta memoria.

    PS1: Se opti per l'allocazione dinamica dai un'occhiata agli smart pointer di c++: std::unique_ptr e std::shared_ptr
    PS2: Probabilmente le componenti dei colori sarebbe meglio definirle come tipo <uint8_t>
    PS3: Usare variabili allocate staticamente è quasi sempre una cattiva idea dal punto di vista dell'architettura.
  • Re: L'array di una struttura richiede parametri "costanti"

    Grazie mille per le risposte, mi sono documentato sull'allocazione dinamica ed ho optato per l'utilizzo di vettori con i quali ho risolto il problema
  • Re: L'array di una struttura richiede parametri "costanti"

    Io avrei usato strutture della libreria standard per non dover gestire a mano l'allocazione della memoria.
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    struct pixel {
        int R; int G; int B;
    };
    
    int main()
    {
        vector<pixel> v;
        pixel px;
        px.R=128;
        px.G=64;
        px.B=32;
        
        v.push_back(px);    
        
        px.R=12;
        px.G=6;
        px.B=3;
        v.push_back(px);    
        
    	for (auto i: v)
    
        		cout << "Hello World green is:" << i.G<< endl;
    
        return 0;
    }
    
    
Devi accedere o registrarti per scrivere nel forum
4 risposte