[C]Chiarimento su strutture e allocazione memoria

di il
7 risposte

[C]Chiarimento su strutture e allocazione memoria

Ciao a tutti, per un paio di anni ho studiato da autodidatta il linguaggio C poi per vari motivi l'anno scorso ho dovuto interrompere gli studi ma ho ripreso in questi giorni, purtroppo non sono mai riuscito a finire la scuola superiore quindi non ho avuto la possibilità di iscrivermi all'università e di conseguenza ho grosse lacune in materia; tralasciando questa piccola e triste premessa, vorrei avere informazioni su una porzione di codice che ho scritto, funziona ma purtroppo non riesco a capire bene qual'è il reale comportamento del programma.
Spero di riuscire ad avere informazioni da voi in merito perchè non conosco nessuno esperto che mi possa visionare il codice e quindi che possa aiutarmi.
#include <string.h>
#include <stdio.h>
#include <cpuid.h>
#include <limits.h>

int calcolaRatioDaFloat(float ratio_){
	if (ratio_ <= 1.26){return 54;}
	if (ratio_ <= 1.34 && ratio_ >= 1.25){return 43;}
	if (ratio_ <= 1.51 && ratio_ >= 1.33){return 1610;}
	if (ratio_ <= 1.61 && ratio_ >= 1.5){return 53;}
	if (ratio_ <= 1.78 && ratio_ >= 1.66){return 169;}
	if (ratio_ <= 1.89 && ratio_ >= 1.778){return 179;}
	if (ratio_ <= 2.34 && ratio_ >= 1.88){return 219;}
};

struct ScreenStruct{
	unsigned short width,heigth,refresh,ratio;
};
struct ScreenClass{
	struct ScreenStruct(*new)(unsigned short w, unsigned short h, unsigned short r);
}ScreenStruct;

struct ScreenStruct new(unsigned short w, unsigned short h, unsigned short r){
	float ratio= (float)w/(float)h;
	//printf("ratio is %d\n", calcolaRatioDaFloat(ratio));
	printf("%1.64f\n",ratio );
	
	return 
		(struct ScreenStruct){
			.width=w,
			.heigth=h,
			.refresh=r,
			.ratio=calcolaRatioDaFloat(ratio)
		};
}
struct ScreenClass ScreenStruct={.new=&new};


int main(int argc, char const *argv[])
{
	
	printf("size of SCREENSTRUCTURE is %zu\n", sizeof(struct ScreenStruct));
	int n=1;
	struct ScreenStruct c[n];
	c[n]=ScreenStruct.new(1920,1080,60);

	printf("%d\n%d\n%d\n%d\n", c[n].width, c[n].heigth, c[n].refresh, c[n].ratio );
	return 0;
}
principalmente stavo provando ad usare le strutture per creare delle classi, il problema che non sono riuscito a risolvere è che devo per forza definire, prima di compilare, la quantità di strutture mentre il mio obbiettivo è quello di riuscire a rendere questa quantità variabile in runtime magari impostando dei limiti, ma questo è comunque un altro discorso che vedrò più in là.
Quello che non comprendo è qual'è il reale comportamento di new in queste righe:

struct ScreenClass{
	struct ScreenStruct(*new)(unsigned short w, unsigned short h, unsigned short r);
}ScreenStruct;

struct ScreenClass ScreenStruct={.new=&new};
scusate l'ignoranza, andrebbe bene anche solo avere delle informazioni sull'argomento o sapere se questa tecnica ha un nome così da poterla studiare più nel dettaglio.
PS: sò che conviene usare malloc per queste cose ma vorrei evitarlo per ora.

7 Risposte

  • Re: [C]Chiarimento su strutture e allocazione memoria

    Eh, be'! A questo punto son curioso anch'io perché non ho mai visto niente del genere.
  • Re: [C]Chiarimento su strutture e allocazione memoria

    In realtà è molto semplice: new non è altro che un puntatore a funzione. Tale funzione deve tornare il tipo struct ScreenStruct e deve poter ricevere 3 parametri unsigned short.

    Infatti la dichiara la variabile globale
    
    struct ScreenClass ScreenStruct = { .new = &new };
    
    le passa l'indirizzo della funzione che è proprio di quel tipo. Se poi avessero utilizzato dei nomi più "intelligenti" la cosa sarebbe anche più chiara:
    
    struct ScreenClass
    {
    	struct ScreenStruct (*create_func_pointer)(unsigned short w, unsigned short h,unsigned short r);
    };
    
    struct ScreenStruct crete_struct(unsigned short w, unsigned short h, unsigned short r)
    {
    	float ratio = (float) w / (float) h;
    	//printf("ratio is %d\n", calcolaRatioDaFloat(ratio));
    	printf("%1.64f\n", ratio);
    
    	return (struct ScreenStruct ) { .width = w, .heigth = h, .refresh = r, .ratio = calcolaRatioDaFloat(ratio) };
    }
    
    struct ScreenClass ScreenStruct = { .create_func_pointer = crete_struct };
    
  • Re: [C]Chiarimento su strutture e allocazione memoria

    Sarebbe meglio evitare di usare un simbolo con nome new
  • Re: [C]Chiarimento su strutture e allocazione memoria

    Grazie LPs, ora che me lo indichi lo vedo anch'io (da solo mai ci sarei arrivato). Epperò, a questo punto, che senso ha una struttura che ha come unico membro un puntatore a funzione? Non è che ci sono modi meno "estrosi" per ottenere lo stesso risultato?
  • Re: [C]Chiarimento su strutture e allocazione memoria

    Grazie LPs e grazie oregon, continuo pero a non capire se questa funzione occupa lo spazio nello stack o nella memoria globale del programma. se non ho capito male la funzione create_struct viene salvata nella memoria globale, poi viene copiata e inserita nello stack attraverso main... quindi, alla fine della fiera, occupa il doppio*n dello spazio necessario, giusto? se sto dicendo idiozie chiedo scusa, ho provato anche ad usare KCachegrind per avere un grafico della memoria usata, ma non sono riuscito a capire bene ancora come funziona il programma, sono un po' una pippa anche su questo.
    Cmq grazie ancora della precisazione
  • Re: [C]Chiarimento su strutture e allocazione memoria

    AldoBaldo ha scritto:


    Grazie LPs, ora che me lo indichi lo vedo anch'io (da solo mai ci sarei arrivato). Epperò, a questo punto, che senso ha una struttura che ha come unico membro un puntatore a funzione? Non è che ci sono modi meno "estrosi" per ottenere lo stesso risultato?
    Direi che il codice presentato è un "esercizio". In ogni caso potresti avere strutture con molti membri fra cui puntatori a funzione.

    Se effettivamente hai bisogno di un solo puntatore a funzione, puoi tranquillamente dichiarare un puntatore singolo del tipo necessario, tipo
    
    #include <stdio.h>
    
    void my_int_func(int x)
    {
        printf( "%d\n", x );
    }
    
    int main(void)
    {
        void (*foo)(int);
        foo = my_int_func;
    
        foo( 2 );
    
        return 0;
    }
    
  • Re: [C]Chiarimento su strutture e allocazione memoria

    unbreker ha scritto:


    Grazie LPs e grazie oregon, continuo pero a non capire se questa funzione occupa lo spazio nello stack o nella memoria globale del programma. se non ho capito male la funzione create_struct viene salvata nella memoria globale, poi viene copiata e inserita nello stack attraverso main... quindi, alla fine della fiera, occupa il doppio*n dello spazio necessario, giusto? se sto dicendo idiozie chiedo scusa, ho provato anche ad usare KCachegrind per avere un grafico della memoria usata, ma non sono riuscito a capire bene ancora come funziona il programma, sono un po' una pippa anche su questo.
    Cmq grazie ancora della precisazione
    La funzione create_struct fa parte del codice sorgente, resta nella section .text, non so cosa intendi di preciso con memoria globale.

    La variabile ScreenStruct è globale ed inizializzata, quindi finisce nella section .data.

    Nel main poi, tramite ScreenStruct.create_func_pointer(1920, 1080, 60); viene creata una nuova struttura che viene assegnata all'array di strutture c, che è locale nel main e quindi stack allocated.

    Quindi in definitiva l'unica struttura struct ScreenStruct allocata è quella (stack allocated) che finisce in nella variabile c del main.
Devi accedere o registrarti per scrivere nel forum
7 risposte