dimensione di un tipo di dati senza utilizzare sizeof

Ho un tipo di dati, ad esempio X , e voglio conoscere le sue dimensioni senza dichiarare una variabile o un puntatore di quel tipo e, naturalmente, senza usare l’operatore sizeof .

È ansible? Ho pensato di utilizzare file di intestazione standard che contengono dimensioni e gamma di tipi di dati, ma che non funziona con il tipo di dati definito dall’utente.

A mio avviso, questo si inserisce nella categoria “come aggiungo due inte senza usare ++, + = o +?”. È una perdita di tempo. Puoi provare ad evitare i mostri di comportamento indefinito facendo qualcosa di simile.

 size_t size = (size_t)(1 + ((X*)0)); 

Nota che non dichiaro una variabile di tipo o puntatore a X

Bene, io sono un dilettante..ma ho provato questo problema e ho ottenuto la risposta giusta senza usare sizeof. Spero che questo aiuti .. Sto cercando di trovare la dimensione di un intero.

 int *a,*s, v=10; a=&v; s=a; a++; int intsize=(int)a-(int)s; printf("%d",intsize); 

Guarda, sizeof è la struttura linguistica per questo. L’unico, quindi è l’unico modo portatile per raggiungere questo objective.

Per alcuni casi speciali potresti generare un codice non portatile che utilizzava un’altra euristica per capire la dimensione di determinati oggetti [*] (probabilmente facendo in modo che tenessero traccia delle proprie dimensioni), ma dovresti fare tutta la contabilità tu stesso .

[*] Oggetti in un senso molto generale piuttosto che nel senso OOP.

La risposta corretta a questa domanda è “Perché dovrei farlo, quando sizeof () lo fa per me, ed è l’unico metodo portatile per farlo?”

La possibilità di imbottitura impedisce ogni speranza senza la conoscenza delle regole utilizzate per introdurla. E quelli sono dipendenti dall’implementazione.

Puoi risolvere il problema leggendo l’ ABI per il tuo particolare processore, il che spiega come sono strutturate le strutture in memoria. È potenzialmente diverso per ogni processore. Ma a meno che tu non stia scrivendo un compilatore è sorprendente che tu non voglia usare solo sizeof , che è il modo giusto per risolvere questo problema.

Prova questo:

 int a; printf("%u\n", (int)(&a+1)-(int)(&a)); 

Guarda nelle fonti del compilatore. Otterrete :

  • la dimensione dei tipi di dati standard.
  • le regole per il riempimento delle strutture

e da questo, la dimensione attesa di qualsiasi cosa.

Se potessi almeno allocare spazio per la variabile e inserire un po ‘di valore sentinella in esso, potresti cambiarlo a poco a poco, e vedere se il valore cambia, ma questo ancora non ti direbbe alcuna informazione sul riempimento.

se X è datatype:

 #define SIZEOF(X) (unsigned int)( (X *)0+1 ) 

se X è una variabile:

 #define SIZEOF(X) (unsigned int)( (char *)(&X+1)-(char *)(&X) ) 

Prova questo:

  #include int main(){ int *ptr = 0; ptr++; printf("Size of int: %d",ptr); return 0; 

Questo è il codice: il trucco è creare un object puntatore, salvare il suo indirizzo, incrementare il puntatore e quindi sottrarre il nuovo indirizzo dal precedente. Il punto chiave è quando un puntatore viene incrementato, in realtà si sposta della dimensione uguale all’object che sta puntando, quindi qui la dimensione della class (di cui l’object a cui punta).

 #include using namespace std; class abc { int a[5]; float c; }; main() { abc* obj1; long int s1; s1=(int)obj1; obj1++; long int s2=(int)obj1; printf("%d",s2-s1); } 

Saluti

Molte di queste risposte presuppongono che tu sappia come sarà la tua struttura. Credo che questa domanda di intervista abbia lo scopo di chiederti di pensare fuori dagli schemi. Stavo cercando la risposta ma non ho trovato nessuna soluzione che mi piacesse qui. Farò una ipotesi migliore dicendo

 struct foo { int a; banana b; char c; ... }; 

Creando foo [2], ora avrò 2 oggetti consecutivi foo in memoria. Così…

 foo[2] buffer = new foo[2]; foo a = buffer[0]; foo b = buffer[1]; return (&b-&a); 

Supponendo che il mio puntatore aritmetico correttamente, questo dovrebbe essere il biglietto – e il suo portatile! Sfortunatamente cose come il padding, le impostazioni del compilatore, ecc. Giocherebbero anche una parte

Pensieri?

Disponibile dalla soluzione C89 che nel codice utente:

  1. Non dichiara una variabile di tipo X.
  2. Non dichiara un puntatore per digitare X.
  3. Senza usare l’operatore sizeof .

Abbastanza facile da fare usando il codice standard come suggerito da @steve jessop

offsetof(type, member-designator)

che si espande a un’espressione costante intera che ha tipo size_t , il cui valore è l’offset in byte, al membro della struttura …, dall’inizio della sua struttura … C11 §7.19 3

 #include  #include  typedef struct { X member; unsigned char uc; } sud03r_type; int main() { printf("Size X: %zu\n", offsetof(sud03r_type, uc)); return 0; } 

Nota: questo codice utilizza "%zu" che richiede C99 in avanti.

metti questo al tuo codice

quindi controlla l’output del linker (file della mappa)

 unsigned int uint_nabil; unsigned long ulong_nabil; 

otterrai qualcosa come questo;

 uint_nabil 700089a8 00000004 ulong_nabil 700089ac 00000004 

4 è la dimensione !!

Un modo semplice per farlo sarebbe utilizzare gli array. Ora, sappiamo per il fatto che negli array gli elementi dello stesso tipo di dati sono memorizzati in un blocco contiguo di memoria. Quindi, sfruttando questo fatto, sono arrivato a seguire:

 #include  using namespace std; int main() { int arr[2]; int* ptr = &arr[0]; int* ptr1 = &arr[1]; cout <<(size_t)ptr1-(size_t)ptr; } 

Spero che questo ti aiuti.

Prova questo,

 #define sizeof_type( type ) ((size_t)((type*)1000 + 1 )-(size_t)((type*)1000)) 

Per il seguente tipo di dati definito dall’utente,

 struct x { char c; int i; }; sizeof_type(x) = 8 (size_t)((x*)1000 + 1 ) = 1008 (size_t)((x*)1000) = 1000 

Ciò tiene conto del fatto che un byte C ++ non è sempre 8 bit binari e che solo i tipi senza segno hanno un comportamento di overflow ben definito.

 #include  int main () { unsigned int i = 1; unsigned int int_bits = 0; while (i!=0) { i <<= 1; ++int_bits; } unsigned char uc = 1; unsigned int char_bits = 0; while (uc!=0) { uc <<= 1; ++char_bits; } std::cout << "Type int has " << int_bits << "bits.\n"; std::cout << "This would be " << int_bits/8 << " IT bytes and " << int_bits/char_bits << " C++ bytes on your platform.\n"; std::cout << "Anyways, not all bits might be usable by you. Hah.\n"; } 

Sicuramente, potresti anche solo #include o .

  main() { clrscr(); int n; float x,*a,*b;//line 1 a=&x; b=(a+1); printf("size of x is %d", n=(char*)(b)-(char*)a); } 

Con questo script di codice è ansible calcolare la dimensione di qualsiasi dato senza sizeof operator. Modificare il float nella riga 1 con il tipo di cui si desidera calcolare la dimensione

 #include  struct { int a; char c; }; void main() { struct node*temp; printf("%d",(char*)(temp+1)-(char*)temp); } 
 # include struct node { int a; char c; }; void main() { struct node*ptr; ptr=(struct node*)0; printf("%d",++ptr); }