2009-11-29 17 views
5

Ist es möglich, ein (festes) Array zu haben, das seine Elemente im schreibgeschützten Segment der ausführbaren Datei und nicht im Stack speichert? Ich habe diesen Code entwickelt, aber leider ist er sehr unflexibel, wenn es darum geht, Elemente hinzuzufügen, zu verschieben oder zu löschen. Wie kann ich überprüfen, ob die Zeichenfolgen tatsächlich im schreibgeschützten Segment gespeichert sind? Ich versuchte readelf -a Datei, aber es listet nicht die Zeichenfolgen auf.Konstante String-Arrays

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++; 
     } 
} 

I ein Skript am Annahme, dass ein struct für jedes Array automatisch erzeugt und verwendet die richtige Länge für pos und Daten. Gibt es Bedenken hinsichtlich der Speichernutzung? Oder wäre es besser, eine Struktur (wie oben) für alle Strings zu erstellen?

Antwort

1

Kann Ihr C-Compiler keine/alle literalen Strings in einen Nur-Lese-Speicher stecken (z. B. VC++ mit aktiviertem String-Pooling)? Oder fordern Sie explizit, dass sie auf diese Weise sequenziell gespeichert werden?

+0

Ja, ersteres wäre auch in Ordnung. Sollte GCC das nicht schon standardmäßig für alle const Variablen tun? – user206268

21

Ich bin mir nicht sicher, ob ich verstehe Ihre Frage, aber tun Sie nach:

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

Dies erklärt eine konstante Array von Zeigern auf konstante Zeichen.

OK, um Strlen zu vermeiden, wie etwa:

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

Okay, das würde die Dinge tatsächlich einfacher machen, aber ich bevorzuge es, keine NUL-Terminierung für Strings zu verwenden. Ich möchte nicht auf externe Funktionen wie strlen() angewiesen sein, nur um die Länge zu erhalten, wenn man bedenkt, dass sie auch während der Kompilierzeit berechnet werden kann (mit sizeof() - 1). – user206268

+0

Was bedeutet dieses "#" vor dem s? – FrAxl93

+0

# wandelt das Makroargument in eine Zeichenfolge um, z. longword1 wird "longword1". –

0

Diese Frage etwas relevant ist:
String Literals

Wie erwähnt, ist die Speicherung von Zeichenketten in ROM/RAM-Plattform/Implementierung abhängig, sollten Sie keine Vorhersagen dafür machen. Auch das Verwenden eines Skripts zum Lesen und Erstellen von Arrays mit geeigneten Größen und zum Speichern von ihnen ist ziemlich unerwünscht. Sie sollten besser gehen für dynamic memory.

+0

Danke für den Link. Aber wie ist die ROM/RAM-Schwierigkeit mit meinem Problem verbunden? Ich schreibe nicht zur Laufzeit in den String-Puffer. Da die Elemente alle fest sind, ist es nicht sinnvoll, dynamischen Speicher zu verwenden. – user206268