Calcolatore offset campi struct
Un char, un int e un altro char occupano 12 byte, non 6: il calcolatore mostra l'offset di ogni membro, il padding che lo precede e quello finale, con le stesse regole del suo compilatore. Gratis nel suo browser.
- Gratis
- Funziona nel suo browser
- Senza registrazione
- I suoi dati restano sul dispositivo
Esegui gratis nel browser
I compilatori C e C++ collocano ogni membro di una struct a un offset in byte che rispetta l'allineamento naturale del membro, poi riempiono il tipo complessivo affinché gli array della struct restino allineati. I valori pack opzionali modellano struct packed; l'abi opzionale seleziona LP64, LLP64 o ILP32 per le larghezze di long e puntatore.
Come C posiziona i campi: allineamento, padding e sizeof
Per una sequenza di membri nell'ordine di dichiarazione il compilatore mantiene un cursore di byte che parte da zero. Prima di collocare un campo arrotonda il cursore per eccesso a un multiplo dell'allineamento effettivo di quel campo, registra quell'indirizzo come offset del campo e avanza il cursore della size del campo. I byte saltati nell'arrotondamento diventano padding prima del membro e non fanno mai parte dello storage proprio del campo.
Dopo l'ultimo membro il compilatore può inserire padding finale affinché la size totale sia un multiplo dell'allineamento della struttura, definito come il massimo allineamento effettivo tra tutti i membri. Quella size finale è ciò che restituisce sizeof, e ogni indirizzo registrato è ciò che offsetof restituisce per il nome del membro corrispondente.
L'allineamento naturale degli scalari segue l'ABI della piattaforma: sui sistemi LP64 char è un byte allineato a uno, short a due, int a quattro, long e puntatore a otto, float a quattro, double a otto; LLP64 mantiene long a quattro mentre i puntatori restano a otto, e ILP32 usa quattro sia per long sia per i puntatori. Questo calcolatore codifica quelle tabelle così Lei può cambiare ABI senza riscrivere gli elenchi di campi.
Capire quel salto è lo scopo di uno strumento offsetof: dump di memoria, formati di rete e binding generati devono concordare con il compilatore, non con una somma mentale approssimativa delle sole size.
Casi d'uso
Protocolli binari e analisi di dump
Confermi l'offset in byte di ogni campo e il sizeof totale prima di scrivere un decoder di rete o interpretare un dump di memoria rispetto a una struct C.
Binding FFI e multi-ABI
Generi o verifichi layout LP64, LLP64 e ILP32 per lo stesso elenco di membri così i binding nativi corrispondono a ciascun modello di dati di destinazione.
Domande frequenti
Come si calcolano gli offset dei campi di una struct C?
Invii fields come array ordinato di {name, type} (o {name, size, alignment}).
Corrisponde alla macro offsetof?
Sì per i membri scalari sotto l'ABI scelto e il valore pack opzionale. Offset e sizeof seguono le stesse regole di collocazione usate dai compilatori per struct scalari naturali o packed.
Quali ABI sono supportati?
lp64 (predefinito: long e puntatore da 8 byte), llp64 (Windows 64 bit: long 4, puntatore 8) e ilp32 (long e puntatore 4).
Perché il sizeof della mia struct supera la somma dei membri?
Perché il compilatore aggiunge padding. Con char, int e char, tre byte finiscono prima dell'int, che parte dall'offset 4, e altri tre in fondo, così il totale di 12 è un multiplo dell'allineamento della struct, cioè 4.
Come si simula una struct impaccata con #pragma pack?
Scelga un impaccamento di 1, 2, 4 o 8 byte. Ogni membro usa allora il minore tra il suo allineamento naturale e quel valore; senza questa opzione si ottiene la disposizione naturale, senza impaccamento.
Strumenti correlati
Per sviluppatori — accesso via API
Tutto quello che vedi in questa pagina è disponibile anche via API. Questa sezione è per i team che vogliono integrarlo nei propri sistemi; chi non ne ha bisogno può semplicemente usare lo strumento qui sopra.
Endpoint
Autenticazione con Bearer token: un POST mette in coda l'attività e il risultato arriva via webhook o link firmato.
Chiamala dal tuo stack
curl -X POST https://api.kit.forhosting.com/dev/struct-field-offset \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"fields":[{"name":"a","type":"char"},{"name":"b","type":"int"},{"name":"c","type":"char"}]}'const res = await fetch("https://api.kit.forhosting.com/dev/struct-field-offset", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"fields": [
{
"name": "a",
"type": "char"
},
{
"name": "b",
"type": "int"
},
{
"name": "c",
"type": "char"
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev/struct-field-offset",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"fields": [
{
"name": "a",
"type": "char"
},
{
"name": "b",
"type": "int"
},
{
"name": "c",
"type": "char"
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev/struct-field-offset", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"fields":[{"name":"a","type":"char"},{"name":"b","type":"int"},{"name":"c","type":"char"}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"fields":[{"name":"a","type":"char"},{"name":"b","type":"int"},{"name":"c","type":"char"}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev/struct-field-offset", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Esempio di richiesta
{
"fields": [
{
"name": "a",
"type": "char"
},
{
"name": "b",
"type": "int"
},
{
"name": "c",
"type": "char"
}
]
}Esempio di risposta
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev.struct_field_offset",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}L'API è asincrona: ricevi subito un task_id e puoi fare polling fino a 1 richiesta al secondo.
Prezzi
Prezzo pubblicato, senza token né crediti. Se l'attività fallisce, non paghi.
Errori
| HTTP | Codice | Significato |
|---|---|---|
401 | unauthorized | Chiave API mancante o non valida: controlla l'header Authorization. |
402 | insufficient_balance | Credito esaurito: ricarica per continuare a eseguire attività. |
404 | unknown_type | Tipo di attività sconosciuto: controlla il campo type della richiesta. |
429 | rate_limited | Troppe richieste in poco tempo: rallenta e riprova tra qualche secondo. |
Note tecniche
Quel layout è esattamente ciò che riportano la macro offsetof e l'operatore sizeof; eppure contare a mano il padding tra ABI e #pragma pack continua a produrre bug silenziosi in protocolli binari, binding FFI e dump di memoria. Questo calcolatore di offset dei campi di struct accetta un elenco ordinato di campi con tipi scalari C noti oppure size e alignment espliciti, applica le stesse regole di arrotondamento per eccesso di un compilatore e restituisce l'offset di ogni campo, il padding precedente, la size totale della struct, l'allineamento globale e il padding finale. Il percorso gratuito del browser e l'API prepagata condividono un unico modulo analitico puro, così chiavi di esercizi e oracoli di produzione non divergono. Una validazione fallita solleva invalid_input e non viene addebitata.
Come C posiziona i campi: allineamento, padding e sizeof
Quando due campi adiacenti non richiedono padding, padding_before vale zero; quando un char è seguito da un int in layout naturale compaiono tre byte di padding prima dell'int e l'offset salta da uno a quattro.
Contratto di ingresso, packing, ABI, forma della risposta ed errori
Il pack opzionale può essere uno, due, quattro o otto per modellare #pragma pack(n): l'allineamento effettivo di ogni campo diventa il minimo tra l'allineamento naturale e pack. L'abi opzionale predefinito è lp64 e può essere llp64 o ilp32. I membri opachi personalizzati forniscono size intera positiva e alignment potenza di due senza affidarsi alla tabella dei tipi. Invii in POST un corpo JSON con fields come array non vuoto di oggetti, ciascuno con name non vuoto e una stringa type oppure sia size sia alignment in byte. I tipi noti includono char, short, int, long, long long, float, double, bool, la famiglia a larghezza fissa intN_t e uintN_t, e pointer o size_t per interi della dimensione di un indirizzo. Gli alias members e layout sono accettati per l'array. Ometta pack per il layout naturale non packed. Array vuoti, nomi di tipo sconosciuti, alignment non potenza di due, name mancanti e valori pack fuori enum falliscono con invalid_input. In caso di successo il corpo include abi; pack opzionale quando il packing è attivo; field_count; fields con index, name, type, size, natural_alignment, effective_alignment, offset e padding_before; struct_size; struct_alignment; trailing_padding; total_padding; used_bytes (solo somma delle size dei membri); method c_struct_offsetof; e una breve stringa formula. Esempio: char a, int b, char c sotto LP64 naturale produce offset zero, quattro e otto con struct_size dodici e tre byte di padding interno prima di b più tre byte finali affinché la size sia multipla di quattro. Abbini gli offset al proprio dump o generatore di codice; questo endpoint non emette sorgente C, solo i numeri di layout che offsetof e sizeof implicherebbero.
Dove un'API di offset di struct conviene, prezzi e limiti
Programmatori di sistema e reverse engineer usano un calcolatore di offset dei campi di struct per verificare che un layout scritto a mano coincida con il compilatore prima di pubblicare un parser di protocollo binario o un dump di struttura del kernel. La validazione fallita non consuma saldo. Mantenga gli elenchi di campi entro il massimo pubblicato, preferisca tipi con nome per la portabilità e fissi gli offset nei test. I generatori FFI e di binding necessitano di numeri deterministici di offsetof e sizeof per LP64 rispetto a LLP64 Windows così la stessa descrizione di schema può mirare a Linux, macOS e Win64 senza ricompilare un programma sonda su ogni host. I laboratori didattici su allineamento e packing assegnano agli studenti un elenco di campi e un'impostazione pack; un oracolo API puro segnala come errore l'equivoco comune di sommare le size senza padding. Le suite di integrazione continua fissano struct_size e ogni offset affinché un cambio di schema che inserisce un campo o altera flag ABI faccia fallire i test subito. Poiché l'implementazione è parse pura di livello A, ogni chiamata riuscita costa il prezzo base pubblicato $0.002 senza token di modello e senza rete in uscita.
Casi di integrazione
Didattica di allineamento e packing
Consenta agli studenti di confrontare layout naturali e #pragma pack e di vedere padding_before e trailing_padding senza compilare programmi sonda.
Domande tecniche
Cosa fa pack?
pack modella #pragma pack(n). L'allineamento effettivo di ogni campo è min(natural_alignment, n). Ometta pack per il layout naturale (non packed).
Quanto costa il calcolatore di offset dei campi di struct?
Lo strumento nel browser è gratuito. Le richieste API usano il saldo prepagato KIT a $0.002 per chiamata riuscita; l'input non valido non viene addebitato.