2009-11-29 39 views
5

È possibile avere un array (fisso) che memorizza i suoi elementi nel segmento di sola lettura dell'eseguibile e non nello stack? Ho inventato questo codice ma sfortunatamente non è flessibile quando si tratta di aggiungere, spostare o eliminare elementi. Come posso verificare che le stringhe siano effettivamente memorizzate nel segmento di sola lettura? Ho provato a leggere -a file ma non elenca le stringhe.Array di stringhe costanti

typedef struct { 
     int len; 
     int pos[100]; 
     char data[500]; 
} FixedStringArray; 

const FixedStringArray items = { 
     4, 
     { 9, 14, 19, 24 }, 
     "LongWord1Word2Word3Word4" 
} ; 

char* GetItem(FixedStringArray *array, int idx, int *len) { 
     if (idx >= array->len) { 
       /* Out of range */ 
       *len = -1; 
       return NULL; 
     } 

     if (idx > 0) { 
       *len = array->pos[idx] - array->pos[idx - 1]; 
       return & array->data[array->pos[idx - 1]]; 
     } 

     *len = array->pos[idx]; 
     return & array->data[0]; 
} 

void PrintItem(FixedStringArray array, int idx) { 
     int len; 
     char *c; 
     int i = 0; 

     c = GetItem(&array, idx, &len); 

     if (len == -1) return; 

     while (i < len) { 
       printf("%c", *c); 
       *c++; 
       i++; 
     } 
} 

sto considerando uno script che genera automaticamente una struttura per ogni array e usa la lunghezza corretta per pos e dati. Ci sono problemi in termini di utilizzo della memoria? O sarebbe meglio creare una struttura (come sopra) per adattarsi a tutte le stringhe?

risposta

1

Non è possibile che il compilatore C inserisca qualsiasi/tutte le stringhe letterali nella memoria di sola lettura (ad esempio VC++ con il pooling di stringhe abilitato)? O richiedi esplicitamente che vengano memorizzati sequenzialmente in questo modo?

+0

Sì, anche il primo andrebbe bene. Non dovrebbe GCC farlo già di default per tutte le variabili const? – user206268

21

io non sono sicuro di aver capito la tua domanda, ma cosa si intende:

const char * const array[] = { "LongWord1", "Word2", "Word3", "Word4" }; 

Questo dichiara un allineamento costante di puntatori a caratteri costanti.

OK, per evitare strlen, che ne dici:

struct Str { 
    size_t len; 
    char *str; 
}; 
#define STR(s) { sizeof(#s) - 1, #s } 
const struct Str[] = { STR(LongWord1), STR(Word2), STR(Word3), STR(Word4) }; 
+0

Ok, sarebbe davvero più facile, ma preferisco non usare la terminazione NUL per le stringhe. Non voglio dipendere da funzioni esterne come strlen() solo per ottenere la lunghezza considerando che può essere calcolato anche durante la compilazione (usando sizeof() - 1). – user206268

+0

Cosa significa "#" di fronte alla s? – FrAxl93

+0

# trasforma l'argomento macro in una stringa, ad es. longword1 diventa "longword1". –

0

Questa domanda è un po 'rilevante:
String Literals

Come sottolineato, il deposito di stringhe letterali in ROM/RAM è la piattaforma/implementazione dipendente, non dovresti fare previsioni per questo. Anche l'utilizzo di uno script per leggere e creare array di dimensioni appropriate e memorizzarli è abbastanza indesiderabile. Dovresti andare per il dynamic memory.

+0

Grazie per il link. Ma qual è la difficoltà della ROM/RAM in relazione al mio problema? Non scrivo nel buffer delle stringhe durante il runtime. Poiché gli elementi sono tutti fissi, non ha senso utilizzare la memoria dinamica. – user206268